Skip to content
1 change: 1 addition & 0 deletions src/components/menu-bar/community-button.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

.community-button {
box-shadow: 0 0 0 1px $ui-black-transparent;
color: $text-menubar;
}

.community-button-icon {
Expand Down
20 changes: 13 additions & 7 deletions src/components/menu-bar/community-button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,21 @@ const CommunityButton = ({
className,
styles.communityButton
)}
iconClassName={styles.communityButtonIcon}
iconSrc={communityIcon}
onClick={onClick}
>
<FormattedMessage
defaultMessage="See Project Page"
description="Label for see project page button"
id="gui.menuBar.seeProjectPage"
/>
<span style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>
<img
src={communityIcon}
className={styles.communityButtonIcon}
alt="See Project Page"
style={{ filter: (typeof window !== 'undefined' && window.isHighContrast) ? 'invert(1)' : 'none' }}
/>
<FormattedMessage
defaultMessage="See Project Page"
description="Label for see project page button"
id="gui.menuBar.seeProjectPage"
/>
</span>
</Button>
);

Expand Down
1 change: 1 addition & 0 deletions src/components/menu-bar/icon--high-contrast.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 5 additions & 2 deletions src/components/menu-bar/menu-bar.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
font-size: $menu-bar-standard-font-size;
font-weight: bold;
background-color: $motion-primary;
color: $ui-white;
color: $text-menubar;
}
[theme="dark"] .menu-bar {
background-color: $motion-primary-dark;
Expand All @@ -54,6 +54,7 @@

.language-icon {
height: 1.5rem;
color: $text-menubar;
vertical-align: middle;
}

Expand All @@ -71,7 +72,7 @@
display: flex;
padding: 0 0.25rem;
text-decoration: none;
color: $ui-white;
color: $text-menubar;
user-select: none;
align-self: center;
position: relative;
Expand Down Expand Up @@ -116,6 +117,7 @@
.menu-bar-menu {
margin-top: $menu-bar-height;
z-index: $z-index-menu-bar;
color: $text-menubar;
}

.feedback-link {
Expand Down Expand Up @@ -143,6 +145,7 @@

.menu-bar-button {
height: $menu-bar-button-size;
color: $text-menubar;
}

.remix-button {
Expand Down
126 changes: 120 additions & 6 deletions src/components/menu-bar/menu-bar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ import {
languageMenuOpen,
openLoginMenu,
closeLoginMenu,
loginMenuOpen
loginMenuOpen,
openAppearanceMenu,
closeAppearanceMenu,
appearanceMenuOpen
} from '../../reducers/menus';
import { setFileHandle } from '../../reducers/tw.js';

Expand All @@ -72,6 +75,7 @@ import collectMetadata from '../../lib/collect-metadata';
import styles from './menu-bar.css';

import remixIcon from './icon--remix.svg';
import highContrastIcon from './icon--high-contrast.svg';
import dropdownCaret from './dropdown-caret.svg';
import languageIcon from '../language-selector/language-icon.svg';
import aboutIcon from './icon--about.svg';
Expand Down Expand Up @@ -197,6 +201,10 @@ MenuItemLink.propTypes = {
class MenuBar extends React.Component {
constructor(props) {
super(props);
this.state = {
highContrast: false,
darkMode: false
};
bindAll(this, [
'handleClickSeeInside',
'handleClickNew',
Expand All @@ -213,9 +221,47 @@ class MenuBar extends React.Component {
'handleLanguageMouseUp',
'handleRestoreOption',
'getSaveToComputerHandler',
'restoreOptionMessage'
'restoreOptionMessage',
'handleToggleDarkModeNew',
'handleToggleHighContrast',
'handleClickTheme'
]);
}

handleToggleHighContrast() {
this.setState(prevState => {
// wcag high contrast mode
const isHighContrast = !prevState.highContrast;

if (isHighContrast) {
document.documentElement.setAttribute('data-theme', 'high-contrast');
document.body.style.setProperty('--text-menubar', '#000000');
window.isHighContrast = true;
} else {
document.documentElement.removeAttribute('data-theme');
document.body.style.setProperty('--text-menubar', '#FFFFFF');
window.isHighContrast = false;
}

return { highContrast: isHighContrast };
});
}

handleToggleDarkModeNew() {
this.setState(prevState => {
// testing stub
const isDarkMode = !prevState.darkMode;

if (isDarkMode) {
document.documentElement.setAttribute('data-theme', 'dark')
} else {
document.documentElement.removeAttribute('data-theme');
}

return { darkMode: isDarkMode };
});
}

componentDidMount() {
document.addEventListener('keydown', this.handleKeyPress);
}
Expand Down Expand Up @@ -340,6 +386,12 @@ class MenuBar extends React.Component {
}
}

handleClickTheme () {
this.setState(state => ({
dark: !state.dark
}));
}

restoreOptionMessage(deletedItem) {
switch (deletedItem) {
case 'Sprite':
Expand Down Expand Up @@ -492,19 +544,22 @@ class MenuBar extends React.Component {
) : null}
{(this.props.canChangeLanguage) && (<div
className={classNames(styles.menuBarItem, styles.hoverable, styles.languageMenu)}
style={{ minWidth: '32px', justifyContent: 'center', alignItems: 'center', display: 'flex' }}
>
<div>
<div style={{ display: 'flex', alignItems: 'center' }}>
<img
className={styles.languageIcon}
src={languageIcon}
width="24"
height="24"
style={{ marginRight: '4px', filter: this.state.highContrast ? 'invert(1)' : 'none' }}
/>
<img
className={styles.languageCaret}
src={dropdownCaret}
width="8"
height="5"
style={{ marginRight: '4px', filter: this.state.highContrast ? 'invert(1)' : 'none' }}
/>
</div>
<LanguageSelector label={this.props.intl.formatMessage(ariaMessages.language)} />
Expand All @@ -514,12 +569,14 @@ class MenuBar extends React.Component {
<div
className={classNames(styles.menuBarItem, styles.hoverable)}
onMouseUp={this.props.onClickTheme}
style={{ minWidth: '32px', justifyContent: 'center', alignItems: 'center', display: 'flex' }}
>
<img
src={themeIcon}
width="24"
height="24"
draggable={false}
style={{ filter: this.state.highContrast ? 'invert(1)' : 'none', marginRight: '2px' }}
/>
</div>
)}
Expand Down Expand Up @@ -576,6 +633,52 @@ class MenuBar extends React.Component {
</MenuBarMenu>
</div>
</div>}
<div
className={classNames(styles.menuBarItem, styles.hoverable, {
[styles.active]: this.props.openAppearanceMenu
})}
onMouseUp={this.props.onClickAppearance}
>
<FormattedMessage
defaultMessage="Appearance"
description="Text for appearance dropdown menu"
id="gui.menuBar.appearance"
/>
<MenuBarMenu
className={classNames(styles.menuBarMenu)}
open={this.props.appearanceMenuOpen}
place={this.props.isRtl ? 'left' : 'right'}
onRequestClose={this.props.onRequestCloseAppearance}
>
<MenuSection>
<MenuItem
isRtl={this.props.isRtl}
onClick={this.handleToggleHighContrast}
>
<FormattedMessage
defaultMessage="Toggle High Contrast"
// eslint-disable-next-line max-len
description="aaaaa"
id="gui.menuBar.hcontrast"
/>
</MenuItem>
{/*
<MenuItem
isRtl={this.props.isRtl}
onClick={this.handleToggleDarkModeNew}
>
<FormattedMessage
defaultMessage="Toggle Dark Mode"
// eslint-disable-next-line max-len
description="aaaaa"
id="gui.menuBar.dark"
/>
</MenuItem>
*/}
</MenuSection>
</MenuBarMenu>
</div>

{(this.props.canManageFiles) && (
<div
className={classNames(styles.menuBarItem, styles.hoverable, {
Expand Down Expand Up @@ -893,13 +996,15 @@ class MenuBar extends React.Component {
/>
) : null} */}
{this.props.canEditTitle ? (
<div className={classNames(styles.menuBarItem, styles.growable)}>
<div className={classNames(styles.menuBarItem, styles.growable)}
style={{ minWidth: '120px', maxWidth: '200px', marginLeft: '8px', marginRight: '8px', display: 'flex', alignItems: 'center' }}>
<MenuBarItemTooltip
enable
id="title-field"
>
<ProjectTitleInput
className={classNames(styles.titleFieldGrowable)}
style={{ fontSize: '1em', padding: '3px 8px', borderRadius: '6px', border: '1px solid #ccc', background: 'var(--text-menubar, #fff)', color: this.state.highContrast ? '#000' : '#222', boxShadow: '0 1px 2px rgba(0,0,0,0.04)' }}
/>
</MenuBarItemTooltip>
</div>
Expand Down Expand Up @@ -944,14 +1049,18 @@ class MenuBar extends React.Component {
/>)
: (null)}
</div>
<div className={styles.menuBarItem}>
<div className={styles.menuBarItem}
style={{ marginLeft: '8px', marginRight: '8px', display: 'flex', alignItems: 'center' }}>
<a
className={styles.feedbackLink}
href="https://penguinmod.com"
rel="noopener noreferrer"
target="_blank"
style={{ textDecoration: 'none' }}
>
<Button className={styles.feedbackButton}>
<Button className={styles.feedbackButton}
style={this.state.highContrast ? { background: '#000', color: '#fff' } : undefined}
>
<FormattedMessage
defaultMessage="Back to Home"
description="Button to go back to the home page"
Expand Down Expand Up @@ -979,6 +1088,7 @@ MenuBar.propTypes = {
onClickSeeInside: PropTypes.func,
aboutMenuOpen: PropTypes.bool,
accountMenuOpen: PropTypes.bool,
appearanceMenuOpen: PropTypes.bool,
authorId: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
authorThumbnailUrl: PropTypes.string,
authorUsername: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
Expand Down Expand Up @@ -1029,6 +1139,7 @@ MenuBar.propTypes = {
onClickRestorePoints: PropTypes.func,
onClickEdit: PropTypes.func,
onClickFile: PropTypes.func,
onClickAppearance: PropTypes.func,
onClickLanguage: PropTypes.func,
onClickLogin: PropTypes.func,
onClickLogo: PropTypes.func,
Expand Down Expand Up @@ -1081,6 +1192,7 @@ const mapStateToProps = (state, ownProps) => {
return {
aboutMenuOpen: aboutMenuOpen(state),
accountMenuOpen: accountMenuOpen(state),
appearanceMenuOpen: appearanceMenuOpen(state),
authorThumbnailUrl: state.scratchGui.tw.author.thumbnail,
authorUsername: state.scratchGui.tw.author.username,
compileErrors: state.scratchGui.tw.compileErrors,
Expand Down Expand Up @@ -1112,6 +1224,8 @@ const mapDispatchToProps = dispatch => ({
onClickAccount: () => dispatch(openAccountMenu()),
onRequestCloseAccount: () => dispatch(closeAccountMenu()),
onClickFile: () => dispatch(openFileMenu()),
onClickAppearance: () => dispatch(openAppearanceMenu()),
onRequestCloseAppearance: () => dispatch(closeAppearanceMenu()),
onRequestCloseFile: () => dispatch(closeFileMenu()),
onClickEdit: () => dispatch(openEditMenu()),
onRequestCloseEdit: () => dispatch(closeEditMenu()),
Expand Down
4 changes: 2 additions & 2 deletions src/components/menu-bar/project-title-input.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ can set a width for example or what it should do in a flex box (eg. grow).
}

.title-field {
color: $ui-white;
color: $text-menubar;
font-weight: bold;
font-size: .8rem;
}

.title-field::placeholder {
color: $ui-white;
color: $text-menubar;
font-weight: normal;
font-size: .8rem;
font-style: italic;
Expand Down
2 changes: 1 addition & 1 deletion src/components/menu/menu.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/* tw: no max width */
/* max-width: 260px; */
overflow: visible;
color: $ui-white;
color: $text-menubar;;
box-shadow: 0 8px 8px 0 $ui-black-transparent-default;
}
[theme="dark"] .menu {
Expand Down
3 changes: 3 additions & 0 deletions src/components/sprite-info/sprite-info.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
[theme="dark"] .sprite-info {
background-color: $ui-primary;
}
[theme="high-contrast"] .sprite-info {
color: #ffffff;
}

.row {
display: flex;
Expand Down
4 changes: 4 additions & 0 deletions src/components/sprite-selector/sprite-selector.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
border-bottom: 0;
}

[theme="high-contrast"] .sprite-selector .spriteIcon {
filter: invert(1);
}

.sprite-wrapper {
/*
Our goal is to fit sprites evenly in a row without leftover space.
Expand Down
2 changes: 2 additions & 0 deletions src/css/colors.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,5 @@ $extensions-transparent: hsla(194, 100%, 50%, 0.35); /* 35% transparent version
$extensions-light: hsla(203, 100%, 39%, 1); /* opaque version of extensions-transparent, on white bg */

$drop-highlight: hsla(194, 100%, 77%, 1); /* lighter than motion-primary */

$text-menubar: var(--text-menubar, hsla(225, 100%, 100%, 1)); /* #FFFFFF */
Loading