diff --git a/src/components/monitor/default-monitor.jsx b/src/components/monitor/default-monitor.jsx index 992014775..3368519dd 100644 --- a/src/components/monitor/default-monitor.jsx +++ b/src/components/monitor/default-monitor.jsx @@ -10,7 +10,10 @@ const DefaultMonitor = ({categoryColor, label, value}) => (
{value}
@@ -19,7 +22,10 @@ const DefaultMonitor = ({categoryColor, label, value}) => ( ); DefaultMonitor.propTypes = { - categoryColor: PropTypes.string.isRequired, + categoryColor: PropTypes.shape({ + background: PropTypes.string.isRequired, + text: PropTypes.string.isRequired + }).isRequired, label: PropTypes.string.isRequired, value: PropTypes.oneOfType([ PropTypes.string, diff --git a/src/components/monitor/large-monitor.jsx b/src/components/monitor/large-monitor.jsx index 5101ad0a5..64ac32640 100644 --- a/src/components/monitor/large-monitor.jsx +++ b/src/components/monitor/large-monitor.jsx @@ -6,7 +6,10 @@ const LargeMonitor = ({categoryColor, value}) => (
{value}
@@ -14,7 +17,10 @@ const LargeMonitor = ({categoryColor, value}) => ( ); LargeMonitor.propTypes = { - categoryColor: PropTypes.string, + categoryColor: PropTypes.shape({ + background: PropTypes.string.isRequired, + text: PropTypes.string.isRequired + }).isRequired, value: PropTypes.oneOfType([ PropTypes.string, PropTypes.number diff --git a/src/components/monitor/list-monitor-scroller.jsx b/src/components/monitor/list-monitor-scroller.jsx index cfcd6a248..ea0de244e 100644 --- a/src/components/monitor/list-monitor-scroller.jsx +++ b/src/components/monitor/list-monitor-scroller.jsx @@ -41,7 +41,10 @@ class ListMonitorScroller extends React.Component {
{this.props.draggable && this.props.activeIndex === index ? ( @@ -51,6 +54,7 @@ class ListMonitorScroller extends React.Component { autoComplete={false} className={classNames(styles.listInput, 'no-drag')} spellCheck={false} + style={{color: this.props.categoryColor.text}} type="text" value={this.props.activeValue} onBlur={this.props.onDeactivate} @@ -97,7 +101,10 @@ class ListMonitorScroller extends React.Component { ListMonitorScroller.propTypes = { activeIndex: PropTypes.number, activeValue: PropTypes.string, - categoryColor: PropTypes.string, + categoryColor: PropTypes.shape({ + background: PropTypes.string.isRequired, + text: PropTypes.string.isRequired + }).isRequired, draggable: PropTypes.bool, height: PropTypes.number, onActivate: PropTypes.func, diff --git a/src/components/monitor/list-monitor.jsx b/src/components/monitor/list-monitor.jsx index e3422e5b3..4bd9a2563 100644 --- a/src/components/monitor/list-monitor.jsx +++ b/src/components/monitor/list-monitor.jsx @@ -54,7 +54,10 @@ const ListMonitor = ({draggable, label, width, height, value, onResizeMouseDown, ListMonitor.propTypes = { activeIndex: PropTypes.number, - categoryColor: PropTypes.string.isRequired, + categoryColor: PropTypes.shape({ + background: PropTypes.string.isRequired, + text: PropTypes.string.isRequired + }).isRequired, draggable: PropTypes.bool.isRequired, height: PropTypes.number, label: PropTypes.string.isRequired, diff --git a/src/components/monitor/monitor.css b/src/components/monitor/monitor.css index 0947db638..a4011457a 100644 --- a/src/components/monitor/monitor.css +++ b/src/components/monitor/monitor.css @@ -42,7 +42,6 @@ align-items: center; min-width: 40px; text-align: center; - color: white; margin: 0 5px; border-radius: calc($space / 2); padding: 0 2px; @@ -55,7 +54,6 @@ min-width: 3rem; padding: 0.1rem 0.25rem; text-align: center; - color: white; font-size: 1rem; white-space: pre-wrap; transform: translateZ(0); /* Fixes flickering in Safari */ @@ -115,7 +113,6 @@ .list-value { min-width: 40px; text-align: left; - color: white; margin: 0 3px; border-radius: calc($space / 2); border: 1px solid $ui-black-transparent; @@ -161,7 +158,6 @@ padding: 3px 5px; border: 0; background: none; - color: $ui-white; outline: none; font-size: 0.75rem; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; @@ -174,7 +170,6 @@ padding: 0; padding-right: 5px; cursor: pointer; - color: $ui-white; } .add-button { diff --git a/src/components/monitor/monitor.jsx b/src/components/monitor/monitor.jsx index ddb2f2e57..d9ceb9269 100644 --- a/src/components/monitor/monitor.jsx +++ b/src/components/monitor/monitor.jsx @@ -10,17 +10,19 @@ import DefaultMonitor from './default-monitor.jsx'; import LargeMonitor from './large-monitor.jsx'; import SliderMonitor from '../../containers/slider-monitor.jsx'; import ListMonitor from '../../containers/list-monitor.jsx'; +import {getColorsForTheme} from '../../lib/themes/index.js'; import styles from './monitor.css'; -const categories = { - data: '#FF8C1A', - sensing: '#5CB1D6', - sound: '#CF63CF', - looks: '#9966FF', - motion: '#4C97FF', - list: '#FC662C', - extension: '#0FBD8C' +// Map category name to color name used in scratch-blocks Blockly.Colours +const categoryColorMap = { + data: 'data', + sensing: 'sensing', + sound: 'sounds', + looks: 'looks', + motion: 'motion', + list: 'data_lists', + extension: 'pen' }; const modes = { @@ -30,6 +32,14 @@ const modes = { list: ListMonitor }; +const getCategoryColor = (theme, category) => { + const colors = getColorsForTheme(theme); + return { + background: colors[categoryColorMap[category]].primary, + text: colors.text + }; +}; + const MonitorComponent = props => ( ( onDoubleClick={props.mode === 'list' || !props.draggable ? null : props.onNextMode} > {React.createElement(modes[props.mode], { - categoryColor: categories[props.category], + categoryColor: getCategoryColor(props.theme, props.category), ...props })} @@ -122,12 +132,10 @@ const MonitorComponent = props => ( ); -MonitorComponent.categories = categories; - const monitorModes = Object.keys(modes); MonitorComponent.propTypes = { - category: PropTypes.oneOf(Object.keys(categories)), + category: PropTypes.oneOf(Object.keys(categoryColorMap)), componentRef: PropTypes.func.isRequired, draggable: PropTypes.bool.isRequired, label: PropTypes.string.isRequired, @@ -140,7 +148,8 @@ MonitorComponent.propTypes = { onSetModeToDefault: PropTypes.func, onSetModeToLarge: PropTypes.func, onSetModeToSlider: PropTypes.func, - onSliderPromptOpen: PropTypes.func + onSliderPromptOpen: PropTypes.func, + theme: PropTypes.string.isRequired }; MonitorComponent.defaultProps = { diff --git a/src/components/monitor/slider-monitor.jsx b/src/components/monitor/slider-monitor.jsx index 0271b140a..2bda8f593 100644 --- a/src/components/monitor/slider-monitor.jsx +++ b/src/components/monitor/slider-monitor.jsx @@ -12,7 +12,10 @@ const SliderMonitor = ({categoryColor, isDiscrete, label, min, max, value, onSli
{value}
@@ -33,7 +36,10 @@ const SliderMonitor = ({categoryColor, isDiscrete, label, min, max, value, onSli ); SliderMonitor.propTypes = { - categoryColor: PropTypes.string.isRequired, + categoryColor: PropTypes.shape({ + background: PropTypes.string.isRequired, + text: PropTypes.string.isRequired + }).isRequired, isDiscrete: PropTypes.bool, label: PropTypes.string.isRequired, max: PropTypes.number, diff --git a/src/containers/monitor.jsx b/src/containers/monitor.jsx index b952a1836..eee63392e 100644 --- a/src/containers/monitor.jsx +++ b/src/containers/monitor.jsx @@ -213,6 +213,7 @@ class Monitor extends React.Component { min={this.props.min} mode={this.props.mode} targetId={this.props.targetId} + theme={this.props.theme} width={this.props.width} onDragEnd={this.handleDragEnd} onExport={isList ? this.handleExport : null} @@ -250,6 +251,7 @@ Monitor.propTypes = { resizeMonitorRect: PropTypes.func.isRequired, spriteName: PropTypes.string, // eslint-disable-line react/no-unused-prop-types targetId: PropTypes.string, + theme: PropTypes.string, toolboxXML: PropTypes.string, // eslint-disable-line react/no-unused-prop-types value: PropTypes.oneOfType([ PropTypes.string, @@ -264,8 +266,12 @@ Monitor.propTypes = { x: PropTypes.number, y: PropTypes.number }; +Monitor.defaultProps = { + theme: 'standard' +}; const mapStateToProps = state => ({ monitorLayout: state.scratchGui.monitorLayout, + theme: state.scratchGui.theme.theme, // render on toolbox updates since changes to the blocks could affect monitor labels, i.e. updated locale toolboxXML: state.scratchGui.toolbox.toolboxXML, vm: state.scratchGui.vm diff --git a/src/lib/themes/high-contrast.js b/src/lib/themes/high-contrast.js index d7abd0674..dc77490b5 100644 --- a/src/lib/themes/high-contrast.js +++ b/src/lib/themes/high-contrast.js @@ -70,9 +70,6 @@ const blockColors = { tertiary: '#FF3355', quaternary: '#FFE5EA' }, - // For productionizing: we should look into making this field be the color of the text on the blocks - // e.g. move and steps in move (10) steps, and rename this property below for controlling the text inside - // of inputs e.g. 10 text: '#000000', textFieldText: '#000000', // Text inside of inputs e.g. 90 in [point in direction (90)] toolboxText: '#000000', // Toolbox text, color picker text (used to be #575E75) diff --git a/test/unit/components/monitor-list.test.jsx b/test/unit/components/monitor-list.test.jsx index 051632ea4..5a3cdf4b2 100644 --- a/test/unit/components/monitor-list.test.jsx +++ b/test/unit/components/monitor-list.test.jsx @@ -11,6 +11,9 @@ describe('MonitorListComponent', () => { monitors: {}, savedMonitorPositions: {} }, + theme: { + theme: 'standard' + }, toolbox: { toolboxXML: '' }, diff --git a/test/unit/components/monitor.test.jsx b/test/unit/components/monitor.test.jsx new file mode 100644 index 000000000..a60ca0923 --- /dev/null +++ b/test/unit/components/monitor.test.jsx @@ -0,0 +1,55 @@ +import React from 'react'; +import {shallow} from 'enzyme'; +import DefaultMonitor from '../../../src/components/monitor/default-monitor'; +import Monitor from '../../../src/components/monitor/monitor'; + +jest.mock('../../../src/lib/themes/default-colors'); +jest.mock('../../../src/lib/themes/dark-mode'); + +describe('Monitor Component', () => { + test('it selects the correct colors based on default theme', () => { + const noop = () => {}; + + const wrapper = shallow(); + + const defaultMonitor = wrapper.find(DefaultMonitor); + + // selects colors from mock value in src/lib/themes/__mocks__/default-colors.js + expect(defaultMonitor.props().categoryColor).toEqual({background: '#111111', text: '#444444'}); + }); + + test('it selects the correct colors based on dark mode theme', () => { + const noop = () => {}; + + const wrapper = shallow(); + + const defaultMonitor = wrapper.find(DefaultMonitor); + + // selects colors from mock value in src/lib/themes/__mocks__/dark-mode.js + expect(defaultMonitor.props().categoryColor).toEqual({background: '#AAAAAA', text: '#BBBBBB'}); + }); +});