Skip to content

Commit 77fd047

Browse files
committed
Merge branch 'fix/toolbar-title' of https://github.com/lindapaiste/p5.js-web-editor into dewanshmobile/mobilenav
2 parents 5547591 + a49f834 commit 77fd047

File tree

8 files changed

+73
-127
lines changed

8 files changed

+73
-127
lines changed

client/constants.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ export const PROJECT_SAVE_SUCCESS = 'PROJECT_SAVE_SUCCESS';
3030
export const PROJECT_SAVE_FAIL = 'PROJECT_SAVE_FAIL';
3131
export const NEW_PROJECT = 'NEW_PROJECT';
3232
export const RESET_PROJECT = 'RESET_PROJECT';
33-
export const SHOW_EDIT_PROJECT_NAME = 'SHOW_EDIT_PROJECT_NAME';
34-
export const HIDE_EDIT_PROJECT_NAME = 'HIDE_EDIT_PROJECT_NAME';
3533

3634
export const SET_PROJECT = 'SET_PROJECT';
3735
export const SET_PROJECTS = 'SET_PROJECTS';

client/modules/IDE/actions/project.js

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -351,18 +351,6 @@ export function cloneProject(project) {
351351
};
352352
}
353353

354-
export function showEditProjectName() {
355-
return {
356-
type: ActionTypes.SHOW_EDIT_PROJECT_NAME
357-
};
358-
}
359-
360-
export function hideEditProjectName() {
361-
return {
362-
type: ActionTypes.HIDE_EDIT_PROJECT_NAME
363-
};
364-
}
365-
366354
export function setProjectSavedTime(updatedAt) {
367355
return {
368356
type: ActionTypes.SET_PROJECT_SAVED_TIME,

client/modules/IDE/components/EditableInput.jsx

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,36 @@ function EditableInput({
1111
emptyPlaceholder,
1212
InputComponent,
1313
inputProps,
14-
onChange
14+
onChange,
15+
disabled,
16+
'aria-label': ariaLabel
1517
}) {
1618
const [isEditing, setIsEditing] = React.useState(false);
1719
const [currentValue, setCurrentValue] = React.useState(value || '');
1820
const displayValue = currentValue || emptyPlaceholder;
1921
const hasValue = currentValue !== '';
2022
const classes = `editable-input editable-input--${
2123
isEditing ? 'is-editing' : 'is-not-editing'
22-
} editable-input--${hasValue ? 'has-value' : 'has-placeholder'}`;
23-
const inputRef = React.createRef();
24+
} editable-input--${hasValue ? 'has-value' : 'has-placeholder'} ${
25+
disabled ? 'editable-input--disabled' : ''
26+
}`;
27+
const inputRef = React.useRef();
2428
const { t } = useTranslation();
2529
React.useEffect(() => {
2630
if (isEditing) {
27-
inputRef.current.focus();
31+
inputRef.current?.focus();
2832
}
2933
}, [isEditing]);
3034

3135
function beginEditing() {
3236
setIsEditing(true);
3337
}
3438

39+
function cancelEditing() {
40+
setIsEditing(false);
41+
setCurrentValue(value);
42+
}
43+
3544
function doneEditing() {
3645
setIsEditing(false);
3746

@@ -51,6 +60,8 @@ function EditableInput({
5160
function checkForKeyAction(event) {
5261
if (event.key === 'Enter') {
5362
doneEditing();
63+
} else if (event.key === 'Escape' || event.key === 'Esc') {
64+
cancelEditing();
5465
}
5566
}
5667

@@ -59,7 +70,11 @@ function EditableInput({
5970
<button
6071
className="editable-input__label"
6172
onClick={beginEditing}
62-
aria-label={t('EditableInput.EditValue', { display: displayValue })}
73+
aria-label={
74+
ariaLabel ?? t('EditableInput.EditValue', { display: displayValue })
75+
}
76+
aria-hidden={isEditing}
77+
disabled={disabled}
6378
>
6479
<span>{displayValue}</span>
6580
<EditIcon
@@ -74,9 +89,10 @@ function EditableInput({
7489
type="text"
7590
{...inputProps}
7691
disabled={!isEditing}
92+
aria-hidden={!isEditing}
7793
onBlur={doneEditing}
7894
onChange={updateValue}
79-
onKeyPress={checkForKeyAction}
95+
onKeyDown={checkForKeyAction}
8096
ref={inputRef}
8197
value={currentValue}
8298
/>
@@ -89,7 +105,9 @@ EditableInput.defaultProps = {
89105
InputComponent: 'input',
90106
inputProps: {},
91107
validate: () => true,
92-
value: ''
108+
value: '',
109+
disabled: false,
110+
'aria-label': undefined
93111
};
94112

95113
EditableInput.propTypes = {
@@ -99,7 +117,9 @@ EditableInput.propTypes = {
99117
inputProps: PropTypes.object, // eslint-disable-line
100118
onChange: PropTypes.func.isRequired,
101119
validate: PropTypes.func,
102-
value: PropTypes.string
120+
value: PropTypes.string,
121+
disabled: PropTypes.bool,
122+
'aria-label': PropTypes.string
103123
};
104124

105125
export default EditableInput;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React from 'react';
2+
import { useTranslation } from 'react-i18next';
3+
import { useSelector } from 'react-redux';
4+
import { useSketchActions } from '../../hooks';
5+
import { selectProjectName } from '../../selectors/project';
6+
import EditableInput from '../EditableInput';
7+
8+
export default function ProjectName() {
9+
const { t } = useTranslation();
10+
11+
const { changeSketchName, canEditProjectName } = useSketchActions();
12+
13+
const projectName = useSelector(selectProjectName);
14+
15+
return (
16+
<EditableInput
17+
value={projectName}
18+
disabled={!canEditProjectName}
19+
aria-label={t('Toolbar.EditSketchARIA')}
20+
inputProps={{
21+
maxLength: 128,
22+
'aria-label': t('Toolbar.NewSketchNameARIA')
23+
}}
24+
validate={(text) => text.trim().length > 0}
25+
onChange={changeSketchName}
26+
/>
27+
);
28+
}

client/modules/IDE/components/Header/Toolbar.jsx

Lines changed: 4 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
import React, { useRef, useState } from 'react';
1+
import React from 'react';
22
import classNames from 'classnames';
33
import PropTypes from 'prop-types';
44
import { useTranslation } from 'react-i18next';
55
import { useDispatch, useSelector } from 'react-redux';
66
import { Link } from 'react-router-dom';
7-
import {
8-
hideEditProjectName,
9-
showEditProjectName
10-
} from '../../actions/project';
117
import {
128
openPreferences,
139
startAccessibleSketch,
@@ -19,12 +15,11 @@ import {
1915
setGridOutput,
2016
setTextOutput
2117
} from '../../actions/preferences';
22-
import { useSketchActions } from '../../hooks';
2318

2419
import PlayIcon from '../../../../images/play.svg';
2520
import StopIcon from '../../../../images/stop.svg';
2621
import PreferencesIcon from '../../../../images/preferences.svg';
27-
import EditProjectNameIcon from '../../../../images/pencil.svg';
22+
import ProjectName from './ProjectName';
2823

2924
const Toolbar = (props) => {
3025
const { isPlaying, infiniteLoop, preferencesIsVisible } = useSelector(
@@ -35,34 +30,6 @@ const Toolbar = (props) => {
3530
const dispatch = useDispatch();
3631

3732
const { t } = useTranslation();
38-
const { changeSketchName, canEditProjectName } = useSketchActions();
39-
40-
const projectNameInputRef = useRef();
41-
const [nameInputValue, setNameInputValue] = useState(project.name);
42-
43-
function handleKeyPress(event) {
44-
if (event.key === 'Enter') {
45-
dispatch(hideEditProjectName());
46-
projectNameInputRef.current?.blur();
47-
}
48-
}
49-
50-
function handleProjectNameClick() {
51-
if (canEditProjectName) {
52-
dispatch(showEditProjectName());
53-
setTimeout(() => {
54-
projectNameInputRef.current?.focus();
55-
}, 140);
56-
}
57-
}
58-
59-
function handleProjectNameSave() {
60-
const newName = nameInputValue;
61-
if (newName.length > 0) {
62-
dispatch(hideEditProjectName());
63-
changeSketchName(newName);
64-
}
65-
}
6633

6734
const playButtonClass = classNames({
6835
'toolbar__play-button': true,
@@ -76,10 +43,6 @@ const Toolbar = (props) => {
7643
'toolbar__preferences-button': true,
7744
'toolbar__preferences-button--selected': preferencesIsVisible
7845
});
79-
const nameContainerClass = classNames({
80-
'toolbar__project-name-container': true,
81-
'toolbar__project-name-container--editing': project.isEditingName
82-
});
8346

8447
return (
8548
<div className="toolbar">
@@ -130,34 +93,8 @@ const Toolbar = (props) => {
13093
{t('Toolbar.Auto-refresh')}
13194
</label>
13295
</div>
133-
<div className={nameContainerClass}>
134-
<button
135-
className="toolbar__project-name"
136-
onClick={handleProjectNameClick}
137-
disabled={!canEditProjectName}
138-
aria-label={t('Toolbar.EditSketchARIA')}
139-
>
140-
<span>{project.name}</span>
141-
{canEditProjectName && (
142-
<EditProjectNameIcon
143-
className="toolbar__edit-name-button"
144-
focusable="false"
145-
aria-hidden="true"
146-
/>
147-
)}
148-
</button>
149-
<input
150-
type="text"
151-
maxLength="128"
152-
className="toolbar__project-name-input"
153-
aria-label={t('Toolbar.NewSketchNameARIA')}
154-
disabled={!canEditProjectName}
155-
ref={projectNameInputRef}
156-
value={nameInputValue}
157-
onChange={(e) => setNameInputValue(e.target.value)}
158-
onBlur={handleProjectNameSave}
159-
onKeyPress={handleKeyPress}
160-
/>
96+
<div className="toolbar__project-name-container">
97+
<ProjectName />
16198
{(() => {
16299
if (project.owner) {
163100
return (

client/modules/IDE/reducers/project.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,6 @@ const project = (state, action) => {
3737
};
3838
case ActionTypes.RESET_PROJECT:
3939
return initialState();
40-
case ActionTypes.SHOW_EDIT_PROJECT_NAME:
41-
return Object.assign({}, state, { isEditingName: true });
42-
case ActionTypes.HIDE_EDIT_PROJECT_NAME:
43-
return Object.assign({}, state, { isEditingName: false });
4440
case ActionTypes.SET_PROJECT_SAVED_TIME:
4541
return Object.assign({}, state, { updatedAt: action.value });
4642
case ActionTypes.START_SAVING_PROJECT:

client/styles/components/_editable-input.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
button.editable-input__label {
88
display: flex;
9+
align-items: center;
910

1011
@include themify() {
1112
color: getThemifyVariable('inactive-text-color');
@@ -35,6 +36,13 @@ button.editable-input__label {
3536
height: 1.5rem;
3637
}
3738

39+
.editable-input--disabled {
40+
pointer-events: none;
41+
.editable-input__icon {
42+
display: none;
43+
}
44+
}
45+
3846
.editable-input--is-not-editing .editable-input__input,
3947
.editable-input--is-editing .editable-input__label {
4048
display: none;

client/styles/components/_toolbar.scss

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -98,40 +98,23 @@
9898
}
9999

100100
.toolbar__project-name-container {
101-
@include themify() {
102-
border-color: getThemifyVariable('inactive-text-color');
103-
}
104101
margin-left: #{10 / $base-font-size}rem;
105102
padding-left: #{10 / $base-font-size}rem;
106103
display: flex;
107104
align-items: center;
108105
}
109106

110-
.toolbar__project-name {
107+
.toolbar .editable-input__label {
111108
@include themify() {
112109
color: getThemifyVariable('secondary-text-color');
113-
&:hover {
114-
color: getThemifyVariable('logo-color');
115-
& .toolbar__edit-name-button path {
116-
fill: getThemifyVariable('logo-color');
117-
}
110+
& path {
111+
fill: getThemifyVariable('secondary-text-color');
118112
}
119113
}
120-
cursor: pointer;
121-
display: flex;
122-
align-items: center;
123-
124-
.toolbar__project-name-container--editing & {
125-
display: none;
126-
}
127114
}
128115

129-
.toolbar__project-name-input {
130-
display: none;
131-
border: 0px;
132-
.toolbar__project-name-container--editing & {
133-
display: block;
134-
}
116+
.toolbar .editable-input__input {
117+
border: 0;
135118
}
136119

137120
.toolbar__project-owner {
@@ -160,15 +143,3 @@
160143
color:getThemifyVariable('logo-color');
161144
}
162145
}
163-
164-
.toolbar__edit-name-button {
165-
display: inline-block;
166-
vertical-align: top;
167-
width: #{18 / $base-font-size}rem;
168-
height: #{18 / $base-font-size}rem;
169-
@include themify() {
170-
& path {
171-
fill: getThemifyVariable('secondary-text-color');
172-
}
173-
}
174-
}

0 commit comments

Comments
 (0)