Skip to content
This repository has been archived by the owner on Apr 25, 2023. It is now read-only.

Commit

Permalink
fix: prevent extra render, cannot rename layers, cannot display infob…
Browse files Browse the repository at this point in the history
…ox on dataset layers (#65)
  • Loading branch information
rot1024 committed Aug 13, 2021
1 parent 9c69a45 commit e3d6186
Show file tree
Hide file tree
Showing 30 changed files with 419 additions and 324 deletions.
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -181,7 +181,7 @@
"rc-slider": "9.7.1",
"react": "^17.0.1",
"react-accessible-accordion": "^3.3.4",
"react-colorful": "^4.4.4",
"react-colorful": "^5.3.0",
"react-dnd": "^11.1.3",
"react-dnd-html5-backend": "^11.1.3",
"react-dom": "^17.0.1",
Expand Down
10 changes: 0 additions & 10 deletions src/components/atoms/PropertyPane/index.stories.tsx

This file was deleted.

18 changes: 0 additions & 18 deletions src/components/atoms/PropertyPane/index.tsx

This file was deleted.

7 changes: 5 additions & 2 deletions src/components/molecules/EarthEditor/ExportPane/index.tsx
@@ -1,8 +1,6 @@
import React, { useState, useCallback } from "react";
import { useIntl } from "react-intl";
import { styled } from "@reearth/theme";
// TODO: 後で汎用化して PropertyPane をやめる
import Wrapper from "@reearth/components/atoms/PropertyPane";
import Button from "@reearth/components/atoms/Button";
import SelectBox, { Props as SelectBoxProps } from "@reearth/components/atoms/SelectBox";
import Text from "@reearth/components/atoms/Text";
Expand Down Expand Up @@ -47,6 +45,11 @@ const ExportPane: React.FC<Props> = ({ className, show = true, onExport }) => {
) : null;
};

const Wrapper = styled.div`
background: ${props => props.theme.properties};
margin: 14px 0;
`;

const SelectWrapper = styled.div`
display: flex;
align-items: center;
Expand Down
Expand Up @@ -67,10 +67,10 @@ export default function ({
selectRightLayerIds(layers.map(l => l.id));
}, []);

const ok = useCallback(() => onSelect?.(rightLayers.children?.map(l => l.content) ?? []), [
onSelect,
rightLayers.children,
]);
const ok = useCallback(
() => onSelect?.(rightLayers.children?.map(l => l.content) ?? []),
[onSelect, rightLayers.children],
);

const addLayers = useCallback(() => {
const layers = uniqBy(flattenLayers(selectedLeftLayers.current), l => l.id);
Expand Down
@@ -0,0 +1,56 @@
import React, { useState, useEffect, useCallback } from "react";

export default function ({
group,
visible,
visibilityChangeable,
onExpand,
onVisibilityChange,
}: {
group?: boolean;
visible?: boolean;
visibilityChangeable?: boolean;
onExpand?: () => void;
onVisibilityChange?: (visible: boolean) => void;
}) {
const [isHover, toggleHover] = useState(false);
const [showHelp, setShowHelp] = useState(false);
const mouseEnterSec = 1100;

const handleVisibilityChange = useCallback(
(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
if (!visibilityChangeable) return;
event.stopPropagation();
onVisibilityChange?.(!visible);
},
[visible, onVisibilityChange, visibilityChangeable],
);

const handleExpand = useCallback(
(e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
if (!group) return;
e.stopPropagation();
onExpand?.();
},
[onExpand, group],
);

useEffect(() => {
if (isHover) {
const timer = setTimeout(() => {
setShowHelp(true);
}, mouseEnterSec);
return () => clearTimeout(timer);
}
setShowHelp(false);
return;
}, [isHover]);

return {
isHover,
showHelp,
toggleHover,
handleVisibilityChange,
handleExpand,
};
}
@@ -1,14 +1,16 @@
import React, { forwardRef, useState, useEffect, useRef, useCallback } from "react";
import { useClickAway } from "react-use";
import React, { forwardRef } from "react";
import { styled, useTheme } from "@reearth/theme";
import useDoubleClick from "@reearth/util/use-double-click";
import Icon from "@reearth/components/atoms/Icon";
import HelpButton from "@reearth/components/atoms/HelpButton";
import Text from "@reearth/components/atoms/Text";
import fonts from "@reearth/theme/fonts";
import LayerActions from "./LayerActions";
import useDoubleClick from "@reearth/util/use-double-click";

import LayerActions, { Format } from "../LayerActions";
import useHooks from "./hooks";
import useEditable from "./use-editable";

export type Format = "kml" | "czml" | "geojson" | "shape" | "reearth";
export type { Format } from "../LayerActions";

export type DropType = "top" | "bottom" | "bottomOfChildren";

Expand Down Expand Up @@ -40,6 +42,7 @@ export type Props = {
childSelected?: boolean;
dropType?: DropType;
allSiblingsDoesNotHaveChildren?: boolean;
visibilityShown?: boolean;
onClick: () => void;
onExpand?: () => void;
onVisibilityChange?: (isVisible: boolean) => void;
Expand Down Expand Up @@ -75,6 +78,7 @@ const Layer: React.ForwardRefRenderFunction<HTMLDivElement, Props> = (
childSelected,
dropType,
allSiblingsDoesNotHaveChildren,
visibilityShown,
onVisibilityChange,
onClick,
onExpand,
Expand All @@ -85,90 +89,20 @@ const Layer: React.ForwardRefRenderFunction<HTMLDivElement, Props> = (
},
ref,
) => {
const [editing, setEditing] = useState(false);
const [editingName, setEditingName] = useState(title || "");
const [isHover, toggleHover] = useState(false);
const editingNameRef = useRef(editingName);
const [showHelp, setShowHelp] = useState(false);
const mouseEnterSec = 1100;

const handleVisibilityChange = useCallback(
(event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
if (!visibilityChangeable) return;
event.stopPropagation();
onVisibilityChange?.(!visible);
},
[visible, onVisibilityChange, visibilityChangeable],
);

const startEditing = useCallback(() => {
if (!renamable) return;
setEditing(true);
}, [renamable]);
const finishEditing = useCallback(() => {
setEditing(false);
}, []);
const resetEditing = useCallback(() => {
editingNameRef.current = title || "";
setEditingName(title || "");
}, [title]);
const handleKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
finishEditing();
} else if (e.key === "Escape") {
resetEditing();
finishEditing();
}
},
[resetEditing, finishEditing],
);
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
editingNameRef.current = e.currentTarget.value;
setEditingName(e.currentTarget.value);
}, []);

useEffect(() => {
if (isHover) {
const timer = setTimeout(() => {
setShowHelp(true);
}, mouseEnterSec);
return () => clearTimeout(timer);
} else {
setShowHelp(false);
return;
}
}, [isHover]);

useEffect(() => {
resetEditing();
}, [resetEditing]);

useEffect(
() =>
editing
? () => {
if (title !== editingNameRef.current) {
onRename?.(editingNameRef.current);
}
resetEditing();
}
: undefined,
[editing, title, onRename, resetEditing],
);

const inputRef = useRef<HTMLInputElement>(null);
useClickAway(inputRef, finishEditing);
const { isHover, showHelp, handleExpand, handleVisibilityChange, toggleHover } = useHooks({
group,
visibilityChangeable,
visible,
onExpand,
onVisibilityChange,
});

const { editing, editingName, startEditing, inputProps } = useEditable({
name: title,
renamable,
onRename,
});
const [handleClick, handleDoubleClick] = useDoubleClick(onClick, startEditing);
const handleExpand = useCallback(
(e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
if (!group) return;
e.stopPropagation();
onExpand?.();
},
[onExpand, group],
);

const theme = useTheme();

Expand Down Expand Up @@ -209,15 +143,7 @@ const Layer: React.ForwardRefRenderFunction<HTMLDivElement, Props> = (
/>
</LayerIconWrapper>
{editing ? (
<Input
ref={inputRef}
type="text"
value={editingName}
onClick={stopPropagation}
onBlur={finishEditing}
onKeyDown={handleKeyDown}
onChange={handleChange}
/>
<Input type="text" {...inputProps} onClick={stopPropagation} />
) : (
<>
<LayerName
Expand All @@ -231,7 +157,7 @@ const Layer: React.ForwardRefRenderFunction<HTMLDivElement, Props> = (
? theme.layers.disableTextColor
: theme.layers.textColor
}>
{title}
{editingName}
</LayerName>
{group && typeof childrenCount === "number" && showChildrenCount && (
<LayerCount
Expand All @@ -247,7 +173,7 @@ const Layer: React.ForwardRefRenderFunction<HTMLDivElement, Props> = (
{childrenCount}
</LayerCount>
)}
{typeof visible === "boolean" && (
{visibilityShown && (
<Visibility
isVisible={!visible || isHover || selected}
onClick={handleVisibilityChange}>
Expand Down
@@ -0,0 +1,76 @@
import React, { useState, useEffect, useRef, useCallback } from "react";
import { useClickAway } from "react-use";

export default function ({
name,
renamable,
onRename,
}: {
name?: string;
renamable?: boolean;
onClick?: () => void;
onRename?: (name: string) => void;
}) {
const [editing, setEditing] = useState(false);
const [editingName, setEditingName] = useState(name || "");
const editingNameRef = useRef(editingName);

const startEditing = useCallback(() => {
if (!renamable) return;
setEditing(true);
}, [renamable]);

const finishEditing = useCallback(() => {
setEditing(false);
if (name !== editingNameRef.current) {
onRename?.(editingNameRef.current);
}
}, [name, onRename]);

const resetEditing = useCallback(() => {
editingNameRef.current = name || "";
setEditingName(name || "");
}, [name]);

const cancelEditing = useCallback(() => {
resetEditing();
finishEditing();
}, [finishEditing, resetEditing]);

const handleKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter") {
finishEditing();
} else if (e.key === "Escape") {
cancelEditing();
}
},
[cancelEditing, finishEditing],
);

const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
editingNameRef.current = e.currentTarget.value;
setEditingName(e.currentTarget.value);
}, []);

useEffect(() => {
resetEditing();
}, [resetEditing]);

const inputRef = useRef<HTMLInputElement>(null);
useClickAway(inputRef, cancelEditing);

return {
editing,
editingName,
startEditing,
finishEditing,
inputProps: {
value: editingName,
ref: inputRef,
onChange: handleChange,
onKeyDown: handleKeyDown,
onBlur: finishEditing,
},
};
}

0 comments on commit e3d6186

Please sign in to comment.