Skip to content
Snippets Groups Projects
Commit 1b9b6ae2 authored by Christos's avatar Christos
Browse files

Merge branch 'fix-tool-rerenders' into 'master'

Fix tool rerenders

See merge request !188
parents 6de21c59 77cbf59c
No related branches found
No related tags found
1 merge request!188Fix tool rerenders
...@@ -27,7 +27,8 @@ ...@@ -27,7 +27,8 @@
"use-deep-compare-effect": "^1.3.1", "use-deep-compare-effect": "^1.3.1",
"uuid": "^7.0.3", "uuid": "^7.0.3",
"wax-prosemirror-core": "^0.0.20", "wax-prosemirror-core": "^0.0.20",
"wax-prosemirror-utilities": "^0.0.20" "wax-prosemirror-utilities": "^0.0.20",
"@pubsweet/ui-toolkit": "^2.3.1"
}, },
"resolutions": { "resolutions": {
"prosemirror-model": "1.11.0", "prosemirror-model": "1.11.0",
......
/* eslint react/prop-types: 0 */ /* eslint react/prop-types: 0 */
import React, { useContext } from 'react'; import React, { useContext, useMemo } from 'react';
import { WaxContext } from 'wax-prosemirror-core'; import { WaxContext } from 'wax-prosemirror-core';
import MenuButton from '../ui/buttons/MenuButton'; import MenuButton from '../ui/buttons/MenuButton';
...@@ -16,9 +16,9 @@ const Button = ({ view = {}, item }) => { ...@@ -16,9 +16,9 @@ const Button = ({ view = {}, item }) => {
const { dispatch, state } = view; const { dispatch, state } = view;
const handleMouseDown = e => { const handleMouseDown = (e, editorState, editorDispatch) => {
e.preventDefault(); e.preventDefault();
run(state, dispatch); run(editorState, dispatch);
}; };
const isActive = active && active(state, activeViewId); const isActive = active && active(state, activeViewId);
...@@ -26,16 +26,21 @@ const Button = ({ view = {}, item }) => { ...@@ -26,16 +26,21 @@ const Button = ({ view = {}, item }) => {
const isDisabled = const isDisabled =
enable && !enable(state) && !(select && select(state, activeViewId)); enable && !enable(state) && !(select && select(state, activeViewId));
return ( const MenuButtonComponent = useMemo(
<MenuButton () => (
active={isActive || false} <MenuButton
disabled={isDisabled} active={isActive || false}
iconName={icon} disabled={isDisabled}
label={label} iconName={icon}
onMouseDown={handleMouseDown} label={label}
title={title} onMouseDown={e => handleMouseDown(e, view.state, view.dispatch)}
/> title={title}
/>
),
[isActive, isDisabled],
); );
return MenuButtonComponent;
}; };
export default Button; export default Button;
/* eslint react/prop-types: 0 */ /* eslint react/prop-types: 0 */
import React, { useContext, useRef } from 'react'; import React, { useContext, useRef, useMemo } from 'react';
import { WaxContext } from 'wax-prosemirror-core'; import { WaxContext } from 'wax-prosemirror-core';
import styled from 'styled-components'; import styled from 'styled-components';
...@@ -17,25 +17,30 @@ const ImageUpload = ({ item, fileUpload, view }) => { ...@@ -17,25 +17,30 @@ const ImageUpload = ({ item, fileUpload, view }) => {
const inputRef = useRef(null); const inputRef = useRef(null);
const handleMouseDown = () => inputRef.current.click(); const handleMouseDown = () => inputRef.current.click();
return ( const ImageUploadComponent = useMemo(
<Wrapper> () => (
<label htmlFor="file-upload"> <Wrapper>
<MenuButton <label htmlFor="file-upload">
active={false} <MenuButton
disabled={!(item.select && item.select(view.state, activeViewId))} active={false}
iconName={item.icon} disabled={!(item.select && item.select(view.state, activeViewId))}
onMouseDown={handleMouseDown} iconName={item.icon}
title="Upload Image" onMouseDown={handleMouseDown}
/> title="Upload Image"
/>
<input <input
id="file-upload" id="file-upload"
ref={inputRef} ref={inputRef}
onChange={e => fileUpload(e.target.files[0])} onChange={e => fileUpload(e.target.files[0])}
type="file" type="file"
/> />
</label> </label>
</Wrapper> </Wrapper>
),
[],
); );
return ImageUploadComponent;
}; };
export default ImageUpload; export default ImageUpload;
/* eslint react/prop-types: 0 */ /* eslint react/prop-types: 0 */
import React from 'react'; import React, { useMemo } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import Dropdown from '../ui/buttons/Dropdown'; import Dropdown from '../ui/buttons/Dropdown';
...@@ -30,18 +30,22 @@ const ToolGroupComponent = ({ view, tools, name }) => { ...@@ -30,18 +30,22 @@ const ToolGroupComponent = ({ view, tools, name }) => {
: toolsShown.push(tool.renderTool(view)); : toolsShown.push(tool.renderTool(view));
}); });
return ( const MemorizedToolGroupComponent = useMemo(
<Wrapper data-name={name}> () => (
{toolsShown} <Wrapper data-name={name}>
{rest.length > 0 && ( {toolsShown}
<Dropdown {rest.length > 0 && (
iconName="more" <Dropdown
dropComponent={<DropWrapper>{rest}</DropWrapper>} iconName="more"
title="Show more tools" dropComponent={<DropWrapper>{rest}</DropWrapper>}
/> title="Show more tools"
)} />
</Wrapper> )}
</Wrapper>
),
[],
); );
return MemorizedToolGroupComponent;
}; };
export default ToolGroupComponent; export default ToolGroupComponent;
/* eslint react/prop-types: 0 */ /* eslint react/prop-types: 0 */
import React, { useState, useContext } from 'react'; import React, { useState, useContext, useMemo, useEffect, useRef } from 'react';
import { WaxContext } from 'wax-prosemirror-core'; import { WaxContext } from 'wax-prosemirror-core';
import styled from 'styled-components';
import { grid } from '@pubsweet/ui-toolkit';
import Dropdown from '../../ui/buttons/Dropdown'; import MenuButton from '../../ui/buttons/MenuButton';
import InsertTableTool from '../../ui/tables/InsertTableTool'; import InsertTableTool from '../../ui/tables/InsertTableTool';
const Wrapper = styled.div`
font-size: 0;
position: relative;
z-index: 2;
`;
const DropWrapper = styled.div`
margin-top: ${grid(1)};
position: absolute;
background: white;
`;
const CreateTable = ({ view = {}, item }) => { const CreateTable = ({ view = {}, item }) => {
const { const {
view: { main }, view: { main },
...@@ -15,33 +29,68 @@ const CreateTable = ({ view = {}, item }) => { ...@@ -15,33 +29,68 @@ const CreateTable = ({ view = {}, item }) => {
view = main; view = main;
} }
const [showTool, setShowTool] = useState(false); const { state } = view;
const toggleShowTool = () => setShowTool(!showTool);
const { state, dispatch } = view;
const { enable, icon, run, select, title } = item; const { enable, icon, run, select, title } = item;
const ref = useRef();
const [isOpen, setIsOpen] = useState(false);
const dropComponent = ( const dropComponent = (
<InsertTableTool <InsertTableTool
onGridSelect={colRows => { onGridSelect={colRows => handleSelect(colRows, view.state, view.dispatch)}
run(colRows, state, dispatch);
}}
/> />
); );
const handleSelect = (colRows, editorState, editorDispatch) => {
run(colRows, editorState, editorDispatch);
setIsOpen(!isOpen);
};
const isDisabled = const isDisabled =
enable && !enable(state) && !(select && select(state, activeViewId)); enable && !enable(state) && !(select && select(state, activeViewId));
return ( useOnClickOutside(ref, () => setIsOpen(false));
<Dropdown
active={showTool} const MemorizedDropdown = useMemo(
dropComponent={dropComponent} () => (
iconName={icon} <Wrapper ref={ref}>
disabled={isDisabled} <MenuButton
onClick={toggleShowTool} active={isOpen}
title={title} disabled={isDisabled}
/> iconName={icon}
onMouseDown={() => {
setIsOpen(!isOpen);
}}
title={title}
/>
{isOpen && <DropWrapper>{dropComponent}</DropWrapper>}
</Wrapper>
),
[isDisabled, isOpen],
); );
return MemorizedDropdown;
}; };
// Hook
const useOnClickOutside = (ref, handler) => {
useEffect(() => {
const listener = event => {
/* Do nothing if clicking ref's element or descendent elements */
if (!ref.current || ref.current.contains(event.target)) {
return;
}
handler(event);
};
document.addEventListener('mousedown', listener);
document.addEventListener('touchstart', listener);
return () => {
document.removeEventListener('mousedown', listener);
document.removeEventListener('touchstart', listener);
};
}, [ref, handler]);
};
export default CreateTable; export default CreateTable;
/* eslint react/prop-types: 0 */ /* eslint react/prop-types: 0 */
import React, { useState } from 'react'; import React, { useState, useMemo } from 'react';
import MenuButton from '../../ui/buttons/MenuButton'; import MenuButton from '../../ui/buttons/MenuButton';
const TrackChangeEnable = ({ view = {}, item, enabled }) => { const TrackChangeEnable = ({ view = {}, item, enabled }) => {
...@@ -11,15 +11,20 @@ const TrackChangeEnable = ({ view = {}, item, enabled }) => { ...@@ -11,15 +11,20 @@ const TrackChangeEnable = ({ view = {}, item, enabled }) => {
item.run(view.state, view.dispatch); item.run(view.state, view.dispatch);
}; };
return ( const TrackChangeEnableComponent = useMemo(
<MenuButton () => (
active={isEnabled} <MenuButton
disabled={item.enable && !item.enable(view.state)} active={isEnabled}
label="Track Changes" disabled={item.enable && !item.enable(view.state)}
onMouseDown={e => handleMouseDown(e)} label="Track Changes"
title={item.title} onMouseDown={e => handleMouseDown(e)}
/> title={item.title}
/>
),
[isEnabled],
); );
return TrackChangeEnableComponent;
}; };
export default TrackChangeEnable; export default TrackChangeEnable;
import React from 'react'; import React, { useMemo } from 'react';
import { injectable, inject } from 'inversify'; import { injectable, inject } from 'inversify';
import { BlockLevelTools, Tabs, ToolGroups } from 'wax-prosemirror-components'; import { BlockLevelTools, Tabs, ToolGroups } from 'wax-prosemirror-components';
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
...@@ -50,7 +50,12 @@ class DisplayText extends ToolGroup { ...@@ -50,7 +50,12 @@ class DisplayText extends ToolGroup {
}; };
const tabList = [first, second]; const tabList = [first, second];
return <Tabs key={uuidv4()} tabList={tabList} />;
const TabsComponent = useMemo(
() => <Tabs key={uuidv4()} tabList={tabList} />,
[],
);
return TabsComponent;
} }
} }
......
import React, { useState } from 'react'; import React, { useMemo } from 'react';
import { injectable } from 'inversify'; import { injectable } from 'inversify';
import { ToolGroupComponent, ToolGroups } from 'wax-prosemirror-components'; import { ToolGroupComponent, ToolGroups } from 'wax-prosemirror-components';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
...@@ -61,14 +61,20 @@ class ToolGroup { ...@@ -61,14 +61,20 @@ class ToolGroup {
if (this._toolGroups > 0) { if (this._toolGroups > 0) {
return <ToolGroups toolGroups={this._toolGroups} view={view} />; return <ToolGroups toolGroups={this._toolGroups} view={view} />;
} }
return (
<ToolGroupComponent const MemorizedToolGroupComponent = useMemo(
key={uuidv4()} () => (
view={view} <ToolGroupComponent
tools={this._tools} key={uuidv4()}
title={this.title} view={view}
name={name} tools={this._tools}
/> title={this.title}
name={name}
/>
),
[view],
); );
return MemorizedToolGroupComponent;
} }
} }
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment