From 9d1872fd9ad16b76670b80d4be2ac8a34200309d Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Sun, 14 Mar 2021 16:15:58 +0530 Subject: [PATCH 1/4] SCSS to Styled Component - Project Name --- client/modules/IDE/components/ProjectName.jsx | 164 ++++++++++++ client/modules/IDE/components/Toolbar.jsx | 244 ++++++------------ client/styles/components/_toolbar.scss | 56 ---- client/theme.js | 9 + 4 files changed, 248 insertions(+), 225 deletions(-) create mode 100644 client/modules/IDE/components/ProjectName.jsx diff --git a/client/modules/IDE/components/ProjectName.jsx b/client/modules/IDE/components/ProjectName.jsx new file mode 100644 index 0000000000..77ef786787 --- /dev/null +++ b/client/modules/IDE/components/ProjectName.jsx @@ -0,0 +1,164 @@ +import React, { useState, useRef } from 'react'; +import PropTypes from 'prop-types'; +import { useTranslation } from 'react-i18next'; +import styled from 'styled-components'; +import { Link } from 'react-router'; + +import { prop, remSize } from '../../../theme'; + +import EditProjectNameIcon from '../../../images/pencil.svg'; + +const Container = styled.div` + margin-left: ${remSize(10)}; + padding-left: ${remSize(10)}; + height: 70%; + display: flex; + align-items: center; + border-color: ${prop('inactiveTextColor')}; +`; + +const EditNameButton = styled(EditProjectNameIcon)` + display: inline-block; + vertical-align: top; + width: ${remSize(18)}; + height: ${remSize(18)}; + & path { + fill: ${prop('secondaryTextColor')}; + } +`; + +const Name = styled.button` + cursor: pointer; + display: flex; + align-items: center; + color: ${prop('secondaryTextColor')}; + &:hover { + color: ${prop('logoColor')}; + & ${EditNameButton} path { + fill: ${prop('logoColor')}; + } + } + + ${({ isEditingName }) => isEditingName && `display: none;`} +`; + +const Input = styled.input` + display: none; + border: 0px; + ${({ isEditingName }) => isEditingName && `display: block;`} +`; + +const Owner = styled.p` + margin-left: ${remSize(5)}; + color: ${prop('secondaryTextColor')}; +`; + +const ProjectName = (props) => { + const { + owner, + currentUser, + project, + showEditProjectName, + setProjectName, + hideEditProjectName, + saveProject + } = props; + + const { t } = useTranslation(); + + const [projectNameInputValue, setProjectNameInputValue] = useState( + project.name + ); + + const projectNameInputRef = useRef(null); + + const canEditProjectName = + (owner && owner.username && owner.username === currentUser) || + !owner || + !owner.username; + + const handleProjectNameChange = (event) => { + setProjectNameInputValue(event.target.value); + }; + + const handleProjectNameSave = () => { + const newProjectName = projectNameInputValue.trim(); + if (newProjectName.length === 0) { + setProjectNameInputValue(project.name); + } else { + setProjectName(newProjectName); + hideEditProjectName(); + if (project.id) { + saveProject(); + } + } + }; + + const handleKeyPress = (event) => { + if (event.key === 'Enter') { + hideEditProjectName(); + projectNameInputRef.current.blur(); + } + }; + + return ( + + { + if (canEditProjectName) { + showEditProjectName(); + setTimeout(() => projectNameInputRef.current.focus(), 0); + } + }} + disabled={!canEditProjectName} + aria-label={t('Toolbar.EditSketchARIA')} + isEditingName={project.isEditingName} + > + {project.name} + {canEditProjectName && ( + + + {owner && ( + + {t('Toolbar.By')} + {owner.username} + + )} + + ); +}; + +ProjectName.propTypes = { + setProjectName: PropTypes.func.isRequired, + currentUser: PropTypes.string, + owner: PropTypes.shape({ + username: PropTypes.string + }), + project: PropTypes.shape({ + name: PropTypes.string.isRequired, + isEditingName: PropTypes.bool, + id: PropTypes.string + }).isRequired, + showEditProjectName: PropTypes.func.isRequired, + hideEditProjectName: PropTypes.func.isRequired, + saveProject: PropTypes.func.isRequired +}; + +ProjectName.defaultProps = { + owner: undefined, + currentUser: undefined +}; + +export default ProjectName; diff --git a/client/modules/IDE/components/Toolbar.jsx b/client/modules/IDE/components/Toolbar.jsx index f87d80bf34..768fe1d840 100644 --- a/client/modules/IDE/components/Toolbar.jsx +++ b/client/modules/IDE/components/Toolbar.jsx @@ -1,188 +1,94 @@ import PropTypes from 'prop-types'; import React from 'react'; import { connect } from 'react-redux'; -import { Link } from 'react-router'; import classNames from 'classnames'; import { withTranslation } from 'react-i18next'; import * as IDEActions from '../actions/ide'; import * as preferenceActions from '../actions/preferences'; import * as projectActions from '../actions/project'; +import ProjectName from '../components/ProjectName'; + import PlayIcon from '../../../images/play.svg'; import StopIcon from '../../../images/stop.svg'; import PreferencesIcon from '../../../images/preferences.svg'; -import EditProjectNameIcon from '../../../images/pencil.svg'; - -class Toolbar extends React.Component { - constructor(props) { - super(props); - this.handleKeyPress = this.handleKeyPress.bind(this); - this.handleProjectNameChange = this.handleProjectNameChange.bind(this); - this.handleProjectNameSave = this.handleProjectNameSave.bind(this); - - this.state = { - projectNameInputValue: props.project.name - }; - } - - handleKeyPress(event) { - if (event.key === 'Enter') { - this.props.hideEditProjectName(); - this.projectNameInput.blur(); - } - } - - handleProjectNameChange(event) { - this.setState({ projectNameInputValue: event.target.value }); - } - handleProjectNameSave() { - const newProjectName = this.state.projectNameInputValue.trim(); - if (newProjectName.length === 0) { - this.setState({ - projectNameInputValue: this.props.project.name - }); - } else { - this.props.setProjectName(newProjectName); - this.props.hideEditProjectName(); - if (this.props.project.id) { - this.props.saveProject(); - } - } - } +const Toolbar = (props) => { + const playButtonClass = classNames({ + 'toolbar__play-button': true, + 'toolbar__play-button--selected': props.isPlaying + }); + const stopButtonClass = classNames({ + 'toolbar__stop-button': true, + 'toolbar__stop-button--selected': !props.isPlaying + }); + const preferencesButtonClass = classNames({ + 'toolbar__preferences-button': true, + 'toolbar__preferences-button--selected': props.preferencesIsVisible + }); - canEditProjectName() { - return ( - (this.props.owner && - this.props.owner.username && - this.props.owner.username === this.props.currentUser) || - !this.props.owner || - !this.props.owner.username - ); - } - - render() { - const playButtonClass = classNames({ - 'toolbar__play-button': true, - 'toolbar__play-button--selected': this.props.isPlaying - }); - const stopButtonClass = classNames({ - 'toolbar__stop-button': true, - 'toolbar__stop-button--selected': !this.props.isPlaying - }); - const preferencesButtonClass = classNames({ - 'toolbar__preferences-button': true, - 'toolbar__preferences-button--selected': this.props.preferencesIsVisible - }); - const nameContainerClass = classNames({ - 'toolbar__project-name-container': true, - 'toolbar__project-name-container--editing': this.props.project - .isEditingName - }); - - const canEditProjectName = this.canEditProjectName(); - - return ( -
- + + +
+ { + props.setAutorefresh(event.target.checked); }} - aria-label={this.props.t('Toolbar.PlaySketchARIA')} - disabled={this.props.infiniteLoop} - > -
- ); - } -} + + +
+ ); +}; Toolbar.propTypes = { isPlaying: PropTypes.bool.isRequired, diff --git a/client/styles/components/_toolbar.scss b/client/styles/components/_toolbar.scss index 219a85d716..4287aa08f6 100644 --- a/client/styles/components/_toolbar.scss +++ b/client/styles/components/_toolbar.scss @@ -97,50 +97,6 @@ } } -.toolbar__project-name-container { - @include themify() { - border-color: getThemifyVariable('inactive-text-color'); - } - margin-left: #{10 / $base-font-size}rem; - padding-left: #{10 / $base-font-size}rem; - display: flex; - align-items: center; -} - -.toolbar__project-name { - @include themify() { - color: getThemifyVariable('secondary-text-color'); - &:hover { - color: getThemifyVariable('logo-color'); - & .toolbar__edit-name-button path { - fill: getThemifyVariable('logo-color'); - } - } - } - cursor: pointer; - display: flex; - align-items: center; - - .toolbar__project-name-container--editing & { - display: none; - } -} - -.toolbar__project-name-input { - display: none; - border: 0px; - .toolbar__project-name-container--editing & { - display: block; - } -} - -.toolbar__project-owner { - margin-left: #{5 / $base-font-size}rem; - @include themify() { - color: getThemifyVariable('secondary-text-color'); - } -} - .toolbar__autorefresh-label { @include themify() { color: getThemifyVariable('secondary-text-color'); @@ -157,15 +113,3 @@ .checkbox__autorefresh{ cursor: pointer; } - -.toolbar__edit-name-button { - display: inline-block; - vertical-align: top; - width: #{18 / $base-font-size}rem; - height: #{18 / $base-font-size}rem; - @include themify() { - & path { - fill: getThemifyVariable('secondary-text-color'); - } - } -} diff --git a/client/theme.js b/client/theme.js index f22f13adb4..efbc721ed6 100644 --- a/client/theme.js +++ b/client/theme.js @@ -62,7 +62,10 @@ export default { [Theme.light]: { colors, ...common, + logoColor: colors.p5jsPink, primaryTextColor: grays.dark, + secondaryTextColor: grays.mediumDark, + inactiveTextColor: grays.middleDark, backgroundColor: grays.lighter, Button: { @@ -115,7 +118,10 @@ export default { [Theme.dark]: { colors, ...common, + logoColor: colors.p5jsPink, primaryTextColor: grays.lightest, + secondaryTextColor: grays.mediumLight, + inactiveTextColor: grays.middleLight, backgroundColor: grays.darker, Button: { @@ -168,7 +174,10 @@ export default { [Theme.contrast]: { colors, ...common, + logoColor: colors.yellow, primaryTextColor: grays.lightest, + secondaryTextColor: grays.lighter, + inactiveTextColor: grays.light, backgroundColor: grays.darker, Button: { From 35123a2e67d02b4f27399a0451c618bac3293f9f Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Mon, 15 Mar 2021 00:28:30 +0530 Subject: [PATCH 2/4] Specificity added. --- client/modules/IDE/components/ProjectName.jsx | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/client/modules/IDE/components/ProjectName.jsx b/client/modules/IDE/components/ProjectName.jsx index 77ef786787..542fdbdc6e 100644 --- a/client/modules/IDE/components/ProjectName.jsx +++ b/client/modules/IDE/components/ProjectName.jsx @@ -28,18 +28,20 @@ const EditNameButton = styled(EditProjectNameIcon)` `; const Name = styled.button` - cursor: pointer; - display: flex; - align-items: center; - color: ${prop('secondaryTextColor')}; - &:hover { - color: ${prop('logoColor')}; - & ${EditNameButton} path { - fill: ${prop('logoColor')}; + &&& { + cursor: pointer; + display: flex; + align-items: center; + color: ${prop('secondaryTextColor')}; + &:hover { + color: ${prop('logoColor')}; + & ${EditNameButton} path { + fill: ${prop('logoColor')}; + } } - } - ${({ isEditingName }) => isEditingName && `display: none;`} + ${({ isEditingName }) => isEditingName && `display: none;`} + } `; const Input = styled.input` From d90ccffe74a4522a0eef666f8548c40a3d8ed92f Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Mon, 15 Mar 2021 11:17:59 +0530 Subject: [PATCH 3/4] styled component support for tests added --- client/modules/IDE/components/Toolbar.test.jsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/modules/IDE/components/Toolbar.test.jsx b/client/modules/IDE/components/Toolbar.test.jsx index 0d13d633af..19b904738a 100644 --- a/client/modules/IDE/components/Toolbar.test.jsx +++ b/client/modules/IDE/components/Toolbar.test.jsx @@ -1,6 +1,9 @@ import React from 'react'; import lodash from 'lodash'; +import { Provider } from 'react-redux'; +import configureStore from '../../../store'; +import ThemeProvider from '../../App/components/ThemeProvider'; import { fireEvent, render, screen, waitFor } from '../../../test-utils'; import { ToolbarComponent } from './Toolbar'; @@ -38,7 +41,11 @@ const renderComponent = (extraProps = {}) => { extraProps ); - render(); + const initialState = window.__INITIAL_STATE__; + + const store = configureStore(initialState); + + render(); return props; }; From 96c0bde5ff9ec60c094dcbf0928def10dea2a940 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Mon, 15 Mar 2021 12:22:29 +0530 Subject: [PATCH 4/4] Lint fix. --- client/modules/IDE/components/Toolbar.test.jsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/modules/IDE/components/Toolbar.test.jsx b/client/modules/IDE/components/Toolbar.test.jsx index 19b904738a..e5f74fd64a 100644 --- a/client/modules/IDE/components/Toolbar.test.jsx +++ b/client/modules/IDE/components/Toolbar.test.jsx @@ -45,8 +45,13 @@ const renderComponent = (extraProps = {}) => { const store = configureStore(initialState); - render(); - + render( + + + + + + ); return props; };