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 @@
"use-deep-compare-effect": "^1.3.1",
"uuid": "^7.0.3",
"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": {
"prosemirror-model": "1.11.0",
......
/* eslint react/prop-types: 0 */
import React, { useContext } from 'react';
import React, { useContext, useMemo } from 'react';
import { WaxContext } from 'wax-prosemirror-core';
import MenuButton from '../ui/buttons/MenuButton';
......@@ -16,9 +16,9 @@ const Button = ({ view = {}, item }) => {
const { dispatch, state } = view;
const handleMouseDown = e => {
const handleMouseDown = (e, editorState, editorDispatch) => {
e.preventDefault();
run(state, dispatch);
run(editorState, dispatch);
};
const isActive = active && active(state, activeViewId);
......@@ -26,16 +26,21 @@ const Button = ({ view = {}, item }) => {
const isDisabled =
enable && !enable(state) && !(select && select(state, activeViewId));
return (
<MenuButton
active={isActive || false}
disabled={isDisabled}
iconName={icon}
label={label}
onMouseDown={handleMouseDown}
title={title}
/>
const MenuButtonComponent = useMemo(
() => (
<MenuButton
active={isActive || false}
disabled={isDisabled}
iconName={icon}
label={label}
onMouseDown={e => handleMouseDown(e, view.state, view.dispatch)}
title={title}
/>
),
[isActive, isDisabled],
);
return MenuButtonComponent;
};
export default Button;
/* 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 styled from 'styled-components';
......@@ -17,25 +17,30 @@ const ImageUpload = ({ item, fileUpload, view }) => {
const inputRef = useRef(null);
const handleMouseDown = () => inputRef.current.click();
return (
<Wrapper>
<label htmlFor="file-upload">
<MenuButton
active={false}
disabled={!(item.select && item.select(view.state, activeViewId))}
iconName={item.icon}
onMouseDown={handleMouseDown}
title="Upload Image"
/>
const ImageUploadComponent = useMemo(
() => (
<Wrapper>
<label htmlFor="file-upload">
<MenuButton
active={false}
disabled={!(item.select && item.select(view.state, activeViewId))}
iconName={item.icon}
onMouseDown={handleMouseDown}
title="Upload Image"
/>
<input
id="file-upload"
ref={inputRef}
onChange={e => fileUpload(e.target.files[0])}
type="file"
/>
</label>
</Wrapper>
<input
id="file-upload"
ref={inputRef}
onChange={e => fileUpload(e.target.files[0])}
type="file"
/>
</label>
</Wrapper>
),
[],
);
return ImageUploadComponent;
};
export default ImageUpload;
/* eslint react/prop-types: 0 */
import React from 'react';
import React, { useMemo } from 'react';
import styled from 'styled-components';
import Dropdown from '../ui/buttons/Dropdown';
......@@ -30,18 +30,22 @@ const ToolGroupComponent = ({ view, tools, name }) => {
: toolsShown.push(tool.renderTool(view));
});
return (
<Wrapper data-name={name}>
{toolsShown}
{rest.length > 0 && (
<Dropdown
iconName="more"
dropComponent={<DropWrapper>{rest}</DropWrapper>}
title="Show more tools"
/>
)}
</Wrapper>
const MemorizedToolGroupComponent = useMemo(
() => (
<Wrapper data-name={name}>
{toolsShown}
{rest.length > 0 && (
<Dropdown
iconName="more"
dropComponent={<DropWrapper>{rest}</DropWrapper>}
title="Show more tools"
/>
)}
</Wrapper>
),
[],
);
return MemorizedToolGroupComponent;
};
export default ToolGroupComponent;
/* 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 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';
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 {
view: { main },
......@@ -15,33 +29,68 @@ const CreateTable = ({ view = {}, item }) => {
view = main;
}
const [showTool, setShowTool] = useState(false);
const toggleShowTool = () => setShowTool(!showTool);
const { state, dispatch } = view;
const { state } = view;
const { enable, icon, run, select, title } = item;
const ref = useRef();
const [isOpen, setIsOpen] = useState(false);
const dropComponent = (
<InsertTableTool
onGridSelect={colRows => {
run(colRows, state, dispatch);
}}
onGridSelect={colRows => handleSelect(colRows, view.state, view.dispatch)}
/>
);
const handleSelect = (colRows, editorState, editorDispatch) => {
run(colRows, editorState, editorDispatch);
setIsOpen(!isOpen);
};
const isDisabled =
enable && !enable(state) && !(select && select(state, activeViewId));
return (
<Dropdown
active={showTool}
dropComponent={dropComponent}
iconName={icon}
disabled={isDisabled}
onClick={toggleShowTool}
title={title}
/>
useOnClickOutside(ref, () => setIsOpen(false));
const MemorizedDropdown = useMemo(
() => (
<Wrapper ref={ref}>
<MenuButton
active={isOpen}
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;
/* eslint react/prop-types: 0 */
import React, { useState } from 'react';
import React, { useState, useMemo } from 'react';
import MenuButton from '../../ui/buttons/MenuButton';
const TrackChangeEnable = ({ view = {}, item, enabled }) => {
......@@ -11,15 +11,20 @@ const TrackChangeEnable = ({ view = {}, item, enabled }) => {
item.run(view.state, view.dispatch);
};
return (
<MenuButton
active={isEnabled}
disabled={item.enable && !item.enable(view.state)}
label="Track Changes"
onMouseDown={e => handleMouseDown(e)}
title={item.title}
/>
const TrackChangeEnableComponent = useMemo(
() => (
<MenuButton
active={isEnabled}
disabled={item.enable && !item.enable(view.state)}
label="Track Changes"
onMouseDown={e => handleMouseDown(e)}
title={item.title}
/>
),
[isEnabled],
);
return TrackChangeEnableComponent;
};
export default TrackChangeEnable;
import React from 'react';
import React, { useMemo } from 'react';
import { injectable, inject } from 'inversify';
import { BlockLevelTools, Tabs, ToolGroups } from 'wax-prosemirror-components';
import { isEmpty } from 'lodash';
......@@ -50,7 +50,12 @@ class DisplayText extends ToolGroup {
};
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 { ToolGroupComponent, ToolGroups } from 'wax-prosemirror-components';
import { v4 as uuidv4 } from 'uuid';
......@@ -61,14 +61,20 @@ class ToolGroup {
if (this._toolGroups > 0) {
return <ToolGroups toolGroups={this._toolGroups} view={view} />;
}
return (
<ToolGroupComponent
key={uuidv4()}
view={view}
tools={this._tools}
title={this.title}
name={name}
/>
const MemorizedToolGroupComponent = useMemo(
() => (
<ToolGroupComponent
key={uuidv4()}
view={view}
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