Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor: Layer renaming #11477

Merged
merged 37 commits into from
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
210fe10
[9248] renaming layers
mariana-k May 11, 2022
b80e023
[9248] added feature toggle, RCM, Context menu
mariana-k May 12, 2022
0045794
[9248] fixed property
mariana-k May 12, 2022
67f71be
[9248] keyboard events, input for layer naming
mariana-k May 12, 2022
baaa379
[9248] fixed focus issue
mariana-k May 12, 2022
abd988f
[9248] disabled renaming locked and background
mariana-k May 12, 2022
3392e5e
[9248] styled layer name input
mariana-k May 12, 2022
623a36c
[9248] fixed eslint errors
mariana-k May 12, 2022
90ffd44
[9248] disabled naming of locked layers from RCM
mariana-k May 12, 2022
ab12f97
[9248] fixed input margins
mariana-k May 13, 2022
77bd224
[9248] renamed isEditable property to isRenamable
mariana-k May 13, 2022
bdc4fc0
Merge branch 'main' into feature/9248
mariana-k May 13, 2022
7b9d014
[9248] fixed layerName, double click condition, enabled renaming lock…
mariana-k May 13, 2022
3d8aced
[9248] used getLayerName method
mariana-k May 13, 2022
b27ad34
Merge branch 'main' into feature/9248
mariana-k May 16, 2022
0b4cdc0
[9248] moved code to canvas provider, fixed layers menu opening on co…
mariana-k May 17, 2022
cb90f8c
[9248] toggle renamable, canvas focus, aria label
mariana-k May 17, 2022
d1b1ef2
[9248] fixed focus, context and layers menus
mariana-k May 17, 2022
5f09465
[9248] changed disabling of renaming mode
mariana-k May 18, 2022
3b3662f
[9248] fixes with eslint
mariana-k May 18, 2022
aa5daa1
[9248] fixed opening layers menu
mariana-k May 18, 2022
3407356
[9248] fixed eslint errors
mariana-k May 18, 2022
74fd699
[9248] fixed focus
mariana-k May 18, 2022
6e677fc
[9248] tests for renaming layer on double click
mariana-k May 18, 2022
43d24cf
[9248] removed focus from the new tests
mariana-k May 18, 2022
7bf4796
[9248] fixed eslint errors
mariana-k May 19, 2022
80adf7a
[9248] backgorund renaming, layer actions
mariana-k May 23, 2022
24a3e01
Merge branch 'main' into feature/9248
May 25, 2022
ba44d1e
Fixed deps
May 25, 2022
fc5428f
Fixed circular dependency loop
May 26, 2022
0eeedcc
Removed unused code
May 26, 2022
e4741b5
Addressed some additional PR comments
May 26, 2022
9a367ab
Wrapped layer renaming input in a form and added non-empty check
Jun 3, 2022
4a5c7f8
Fixed re-renaming a layer
Jun 6, 2022
1c7826d
Merge branch 'main' into feature/9248
Jun 6, 2022
ded6c3a
Added a missing flag in the karma test
Jun 7, 2022
66c66fa
Renaming and grouping merged!
Jun 7, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions includes/Experiments.php
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,17 @@ public function get_experiments(): array {
'group' => 'editor',
'default' => true,
],
/**
* Author: @mariana-k
* Issue: #9248
* Creation date: 2022-05-12
*/
[
'name' => 'layerNaming',
'label' => __( 'Layer naming', 'web-stories' ),
'description' => __( 'Enable layer naming', 'web-stories' ),
'group' => 'editor',
],
];
}

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 4 additions & 6 deletions packages/elements/src/utils/getLayerName.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,13 @@ import getDefinitionForType from './getDefinitionForType';
* @return {string} Layer name.
*/
function getLayerName(element) {
if (element.isBackground) {
return __('Background', 'web-stories');
}

/* TODO: Enable this when layers can have names:
if (element.layerName) {
return element.layerName;
}
*/

if (element.isBackground) {
return __('Background', 'web-stories');
}

return getDefinitionForType(element.type).getLayerText(element);
}
Expand Down
5 changes: 5 additions & 0 deletions packages/story-editor/src/app/canvas/canvasProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ function CanvasProvider({ children }) {
const [eyedropperPixelData, setEyedropperPixelData] = useState(null);
const [isEyedropperActive, setIsEyedropperActive] = useState(null);
const [eyedropperCallback, setEyedropperCallback] = useState(null);
const [renamableLayer, setRenamableLayer] = useState(null);

// IntersectionObserver tracks clientRects which is what we need here.
// different from use case of useIntersectionEffect because this is extensible
Expand Down Expand Up @@ -217,6 +218,7 @@ function CanvasProvider({ children }) {
boundingBoxes,
clientRectObserver,
onMoveableMount,
renamableLayer,
},
actions: {
setPageContainer,
Expand All @@ -237,6 +239,7 @@ function CanvasProvider({ children }) {
setEyedropperImg,
setEyedropperPixelData,
setMoveableMount,
setRenamableLayer,
},
}),
[
Expand All @@ -256,6 +259,7 @@ function CanvasProvider({ children }) {
eyedropperPixelData,
boundingBoxes,
clientRectObserver,
renamableLayer,
getNodeForElement,
setNodeForElement,
setEditingElementWithoutState,
Expand All @@ -265,6 +269,7 @@ function CanvasProvider({ children }) {
selectIntersection,
onMoveableMount,
setMoveableMount,
setRenamableLayer,
]
);
return (
Expand Down
1 change: 1 addition & 0 deletions packages/story-editor/src/app/rightClickMenu/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const RIGHT_CLICK_MENU_LABELS = {
DUPLICATE_ELEMENTS: (numElements = 1) =>
_n('Duplicate Element', 'Duplicate Elements', numElements, 'web-stories'),
LOCK_UNLOCK: __('Lock/Unlock', 'web-stories'),
RENAME_LAYER: __('Rename Layer', 'web-stories'),
PASTE_IMAGE_STYLES: __('Paste Image Styles', 'web-stories'),
PASTE_SHAPE_STYLES: __('Paste Shape Styles', 'web-stories'),
PASTE_VIDEO_STYLES: __('Paste Video Styles', 'web-stories'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
*/

export { default as LayerLock } from './layerLock';
export { default as LayerName } from './layerName';
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,9 @@ function LayerLock() {
}

return (
<>
<ContextMenuComponents.MenuSeparator />
<ContextMenuComponents.MenuButton onClick={toggleLayerLock}>
{RIGHT_CLICK_MENU_LABELS.LOCK_UNLOCK}
</ContextMenuComponents.MenuButton>
</>
<ContextMenuComponents.MenuButton onClick={toggleLayerLock}>
{RIGHT_CLICK_MENU_LABELS.LOCK_UNLOCK}
</ContextMenuComponents.MenuButton>
);
}

Expand Down
60 changes: 60 additions & 0 deletions packages/story-editor/src/app/rightClickMenu/items/layerName.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2022 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* External dependencies
*/
import { ContextMenuComponents } from '@googleforcreators/design-system';
import { useCallback } from '@googleforcreators/react';
import { useFeature } from 'flagged';

/**
* Internal dependencies
*/
import { RIGHT_CLICK_MENU_LABELS } from '../constants';
import { useCanvas, useStory } from '../..';

function LayerName() {
const { selectedElementIds } = useStory(({ state }) => ({
selectedElementIds: state.selectedElementIds,
}));
const { setRenamableLayer } = useCanvas(({ state, actions }) => ({
setRenamableLayer: actions.setRenamableLayer,
renamableLayer: state.renamableLayer,
}));
const enableLayerNaming = useCallback(() => {
setRenamableLayer({
elementId: selectedElementIds[0],
});
}, [setRenamableLayer, selectedElementIds]);

const isLayerNamingEnabled = useFeature('layerNaming');

if (!isLayerNamingEnabled) {
return null;
}

return (
<>
<ContextMenuComponents.MenuSeparator />
<ContextMenuComponents.MenuButton onClick={enableLayerNaming}>
{RIGHT_CLICK_MENU_LABELS.RENAME_LAYER}
</ContextMenuComponents.MenuButton>
</>
);
}

export default LayerName;
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { useStory, useLocalMedia } from '../..';
import useVideoTrim from '../../../components/videoTrim/useVideoTrim';
import useRightClickMenu from '../useRightClickMenu';
import useLayerSelect from '../useLayerSelect';
import { LayerLock } from '../items';
import { LayerLock, LayerName } from '../items';
import {
DEFAULT_DISPLACEMENT,
MenuPropType,
Expand Down Expand Up @@ -182,6 +182,7 @@ function ForegroundMediaMenu({ parentMenuRef }) {
</ContextMenuComponents.MenuShortcut>
</ContextMenuComponents.MenuButton>

<LayerName />
<LayerLock />

<ContextMenuComponents.MenuSeparator />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
usePresetActions,
} from '../hooks';
import useLayerSelect from '../useLayerSelect';
import { LayerLock } from '../items';
import { LayerLock, LayerName } from '../items';
import { useStory } from '../..';
import useRightClickMenu from '../useRightClickMenu';
import {
Expand Down Expand Up @@ -156,6 +156,7 @@ function ShapeMenu({ parentMenuRef }) {
</ContextMenuComponents.MenuShortcut>
</ContextMenuComponents.MenuButton>

<LayerName />
<LayerLock />

<ContextMenuComponents.MenuSeparator />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
} from '../constants';
import { useElementActions, useLayerActions } from '../hooks';
import useLayerSelect from '../useLayerSelect';
import { LayerLock } from '../items';
import { LayerLock, LayerName } from '../items';
import useRightClickMenu from '../useRightClickMenu';
import {
DEFAULT_DISPLACEMENT,
Expand Down Expand Up @@ -144,6 +144,7 @@ function StickerMenu({ parentMenuRef }) {
</ContextMenuComponents.MenuShortcut>
</ContextMenuComponents.MenuButton>

<LayerName />
<LayerLock />
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
usePresetActions,
} from '../hooks';
import useLayerSelect from '../useLayerSelect';
import { LayerLock } from '../items';
import { LayerLock, LayerName } from '../items';
import { useStory } from '../..';
import useRightClickMenu from '../useRightClickMenu';
import {
Expand Down Expand Up @@ -156,6 +156,7 @@ function TextMenu({ parentMenuRef }) {
</ContextMenuComponents.MenuShortcut>
</ContextMenuComponents.MenuButton>

<LayerName />
<LayerLock />

<ContextMenuComponents.MenuSeparator />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ function useInsertElement() {
}
});
}

focusCanvas();

return element;
},
[addElement, focusCanvas, setZoomSetting]
Expand Down
12 changes: 11 additions & 1 deletion packages/story-editor/src/components/footer/layers/layers.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* External dependencies
*/
import styled from 'styled-components';
import { useState, useRef } from '@googleforcreators/react';
import { useState, useRef, useEffect } from '@googleforcreators/react';
import { __, sprintf } from '@googleforcreators/i18n';
import { PLACEMENT } from '@googleforcreators/design-system';
/**
Expand All @@ -29,6 +29,7 @@ import { LayerPanel } from '../../panels/design';
import useLayers from '../../panels/design/layer/useLayers';
import Popup, { NavigationWrapper } from '../../secondaryPopup';
import { ToggleButton } from '../../toggleButton';
import { useCanvas } from '../../../app';

const Container = styled.div`
background-color: ${({ theme }) => theme.colors.bg.secondary};
Expand All @@ -43,6 +44,15 @@ function Layers() {
const layersLength = useLayers().length;
const [isOpen, setIsOpen] = useState(false);
const ref = useRef();
const { renamableLayer } = useCanvas(({ state }) => ({
renamableLayer: state.renamableLayer,
}));

useEffect(() => {
if (renamableLayer) {
setIsOpen(true);
}
}, [renamableLayer]);

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,69 @@ describe('Layer Panel', () => {
).toBeTrue();
});

it('should be able to rename a layer by clicking Enter', async () => {
await fixture.events.click(fixture.editor.sidebar.insertTab);
await fixture.editor.library.textTab.click();
await fixture.events.click(fixture.editor.library.text.preset('Title 1'));

const titleLayer = layerPanel.getLayerByInnerText('Title 1');

await fixture.events.click(titleLayer, { clickCount: 2 });
await fixture.events.keyboard.type('New Title Name');
await fixture.events.keyboard.press('Enter');

expect(
layerPanel.layers.filter((layer) => layer.innerText === 'New Title Name')
?.length
).toBe(1);
expect(
layerPanel.layers.filter((layer) => layer.innerText === 'Title 1')?.length
).toBe(0);
});

it('should be able to rename a layer on blur (e.g. clicking on another layer)', async () => {
await fixture.events.click(fixture.editor.sidebar.insertTab);
await fixture.editor.library.textTab.click();
await fixture.events.click(fixture.editor.library.text.preset('Title 1'));

const titleLayer = layerPanel.getLayerByInnerText('Title 1');

await fixture.events.click(titleLayer, { clickCount: 2 });
await fixture.events.keyboard.type('New Title Name');

const bgLayer = layerPanel.getLayerByInnerText('Background');

await fixture.events.click(bgLayer);

expect(
layerPanel.layers.filter((layer) => layer.innerText === 'New Title Name')
?.length
).toBe(1);
expect(
layerPanel.layers.filter((layer) => layer.innerText === 'Title 1')?.length
).toBe(0);
});

it('should be able to exit renaming a layer by clicking Esc', async () => {
await fixture.events.click(fixture.editor.sidebar.insertTab);
await fixture.editor.library.textTab.click();
await fixture.events.click(fixture.editor.library.text.preset('Title 1'));

const titleLayer = layerPanel.getLayerByInnerText('Title 1');

await fixture.events.click(titleLayer, { clickCount: 2 });
await fixture.events.keyboard.type('New Title Name');
await fixture.events.keyboard.press('Esc');

expect(
layerPanel.layers.filter((layer) => layer.innerText === 'New Title Name')
?.length
).toBe(0);
expect(
layerPanel.layers.filter((layer) => layer.innerText === 'Title 1')?.length
).toBe(1);
});

it('should be able to duplicate elements with duplicate action', async () => {
await fixture.events.click(fixture.editor.sidebar.insertTab);
await fixture.editor.library.textTab.click();
Expand Down
Loading