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

Commit

Permalink
fix: Button widget (#111)
Browse files Browse the repository at this point in the history
* add mask function, refact/fix Button widget

* fix open/close issue, refactor

Co-authored-by: KaWaite <[email protected]>
  • Loading branch information
KaWaite and KaWaite authored Oct 25, 2021
1 parent cd19746 commit b934851
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 71 deletions.
162 changes: 93 additions & 69 deletions src/components/molecules/Visualizer/Widget/Button/MenuButton.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React, { useRef, useCallback, useState } from "react";
import { usePopper } from "react-popper";

import Flex from "@reearth/components/atoms/Flex";
import Icon from "@reearth/components/atoms/Icon";
import { fonts, styled, useTheme, usePublishTheme, PublishTheme } from "@reearth/theme";
import Text from "@reearth/components/atoms/Text";
import { styled, usePublishTheme, PublishTheme, metricsSizes, mask } from "@reearth/theme";
import { Camera } from "@reearth/util/value";

import { SceneProperty } from "../../Engine";
Expand Down Expand Up @@ -49,8 +51,7 @@ export default function ({
}: Props): JSX.Element {
const ctx = useContext();
const publishedTheme = usePublishTheme(sceneProperty?.theme);
const theme = useTheme();
const [visibleMenuButton, setVisibleMenuButton] = useState<string>();
const [visibleMenuButton, setVisibleMenuButton] = useState(false);
const flyTo = ctx?.reearth.visualizer.camera.flyTo;

const referenceElement = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -94,116 +95,139 @@ export default function ({
(b: Button | MenuItem) => () => {
const t = "buttonType" in b ? b.buttonType : "menuType" in b ? b.menuType : undefined;
if (t === "menu") {
setVisibleMenuButton(v => (v === b.id ? undefined : b.id));
setVisibleMenuButton(!visibleMenuButton);
return;
}
setVisibleMenuButton(undefined);

if (t === "camera") {
} else if (t === "camera") {
const camera =
"buttonCamera" in b ? b.buttonCamera : "menuCamera" in b ? b.menuCamera : undefined;
if (camera) {
flyTo?.(camera, { duration: 2 });
}
return;
}

let link = "buttonLink" in b ? b.buttonLink : "menuLink" in b ? b.menuLink : undefined;
if (!link) return;

const splitLink = link?.split("/");
if (splitLink?.[0] !== "http:" && splitLink?.[0] !== "https:") {
link = "https://" + link;
} else {
let link = "buttonLink" in b ? b.buttonLink : "menuLink" in b ? b.menuLink : undefined;
if (link) {
const splitLink = link?.split("/");
if (splitLink?.[0] !== "http:" && splitLink?.[0] !== "https:") {
link = "https://" + link;
window.open(link, "_blank", "noopener");
}
}
}
window.open(link, "_blank", "noopener");
setVisibleMenuButton(false);
},
[flyTo],
[flyTo, visibleMenuButton],
);

return (
<Wrapper>
<Wrapper publishedTheme={publishedTheme} button={b}>
<Button
publishedTheme={publishedTheme}
tabIndex={0}
button={b}
onClick={b && handleClick(b)}
ref={referenceElement}>
{(b?.buttonStyle === "icon" || b?.buttonStyle === "texticon") && b?.buttonIcon && (
<StyledIcon icon={b?.buttonIcon} size={25} margin={!!b?.buttonTitle} />
<Icon icon={b?.buttonIcon} size={20} />
)}
{b?.buttonStyle !== "icon" && (
<Text
size="xs"
customColor
otherProperties={{
marginLeft: b?.buttonIcon && b?.buttonStyle === "texticon" ? "5px" : undefined,
}}>
{b?.buttonTitle}
</Text>
)}
{b?.buttonStyle !== "icon" && b?.buttonTitle}
</Button>
<div
ref={popperElement}
style={{
zIndex: theme.zIndexes.dropDown,
...styles.popper,
}}
{...attributes.popper}>
<MenuWrapper ref={popperElement} style={{ ...styles.popper }} {...attributes.popper}>
{visibleMenuButton && (
<MenuWrapper background={publishedTheme.background}>
<MenuInnerWrapper publishedTheme={publishedTheme} button={b}>
{menuItems?.map(i => (
<MenuItem
color={publishedTheme.mainText}
tabIndex={0}
align="center"
publishedTheme={publishedTheme}
key={i.id}
item={i}
button={b}
onClick={handleClick(i)}>
{i.menuType !== "border" && i.menuTitle}
<Flex align="center">
{i.menuIcon && <Icon icon={i.menuIcon} size={20} />}
<Text
size="xs"
customColor
otherProperties={{
marginLeft: i.menuIcon ? "5px" : undefined,
}}>
{i.menuTitle}
</Text>
</Flex>
</MenuItem>
))}
</MenuWrapper>
</MenuInnerWrapper>
)}
</div>
</MenuWrapper>
</Wrapper>
);
}

const Wrapper = styled.div`
margin-left: 5px;
&:first-of-type {
margin-left: 0;
const Wrapper = styled.div<{ button?: Button; publishedTheme: PublishTheme }>`
border-radius: ${metricsSizes["xs"]}px;
&,
> div {
background-color: ${({ button, publishedTheme }) => button?.buttonBgcolor || publishedTheme};
}
`;

const StyledIcon = styled(Icon)<{ margin: boolean }>`
vertical-align: middle;
margin-right: ${({ margin }) => (margin ? "5px" : null)};
`;

const MenuWrapper = styled.div<{ background: string }>`
width: 100%;
background-color: ${({ background }) => background};
border-radius: 3px;
overflow-wrap: break-word;
hyphens: auto;
`;

const MenuItem = styled.a<{ item?: MenuItem; color: string }>`
display: block;
font-size: ${fonts.sizes.xs}px;
margin: ${({ item }) => (item?.menuType === "border" ? "0 5px" : null)};
padding: ${({ item }) => (item?.menuType === "border" ? null : "5px 20px")};
cursor: ${({ item }) => (item?.menuType === "border" ? null : "pointer")};
border-top: ${({ item }) => (item?.menuType === "border" ? "1px solid #fff" : null)};
opacity: ${({ item }) => (item?.menuType === "border" ? "0.5" : null)};
color: ${({ color }) => color};
`;

const Button = styled.div<{ button?: Button; publishedTheme: PublishTheme }>`
display: flex;
border-radius: 3px;
border-radius: ${metricsSizes["xs"]}px;
min-width: 32px;
height: 32px;
padding: 0 10px;
font-size: ${fonts.sizes["2xs"]}px;
line-height: 32px;
box-sizing: border-box;
background-color: ${({ button, publishedTheme }) =>
button?.buttonBgcolor || publishedTheme.background};
color: ${({ button, publishedTheme }) => button?.buttonColor || publishedTheme.mainText};
cursor: pointer;
align-items: center;
user-select: none;
&:hover {
background: ${({ publishedTheme, button }) =>
mask(button?.buttonBgcolor) || publishedTheme.mask};
}
`;

const MenuWrapper = styled.div`
z-index: ${({ theme }) => theme.zIndexes.dropDown};
border-radius: 3px;
max-height: 30vh;
overflow: auto;
-webkit-overflow-scrolling: touch;
`;

const MenuInnerWrapper = styled.div<{ button?: Button; publishedTheme: PublishTheme }>`
min-width: 32px;
width: 100%;
color: ${({ button, publishedTheme }) => button?.buttonColor || publishedTheme.mainText};
overflow-wrap: break-word;
hyphens: auto;
`;

const MenuItem = styled(Flex)<{ item?: MenuItem; button?: Button; publishedTheme: PublishTheme }>`
min-height: ${({ item }) => (item?.menuType === "border" ? null : "25px")};
border-radius: ${({ item }) => (item?.menuType === "border" ? null : "3px")};
padding: ${({ item }) => (item?.menuType === "border" ? "0 10px" : "2px 10px")};
cursor: ${({ item }) => (item?.menuType === "border" ? null : "pointer")};
background: ${({ publishedTheme, item, button }) =>
item?.menuType === "border" ? mask(button?.buttonBgcolor) || publishedTheme.mask : null};
border-bottom: ${({ item, publishedTheme, button }) =>
item?.menuType === "border"
? `1px solid ${button?.buttonColor || publishedTheme.weakText}`
: null};
user-select: none;
&:hover {
background: ${({ publishedTheme, item, button }) =>
item?.menuType === "border" ? null : mask(button?.buttonBgcolor) || publishedTheme.mask};
}
`;
2 changes: 1 addition & 1 deletion src/theme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ export { default as metrics, metricsSizes } from "./metrics";
export { default } from "./darkTheme";
export { default as Provider } from "./provider";
export { default as PublishedAppProvider } from "./publishedAppProvider";
export { usePublishTheme, publishTheme } from "./publishTheme";
export { usePublishTheme, publishTheme, mask } from "./publishTheme";
export type { PublishTheme } from "./publishTheme";
7 changes: 6 additions & 1 deletion src/theme/publishTheme/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ const premade: Record<string, PublishTheme | undefined> = {
forest,
};

export function mask(color?: string) {
if (!color) return;
return isDark(color) ? "rgba(255, 255, 255, 0.15)" : "rgba(0, 0, 0, 0.15)";
}

export function usePublishTheme(sceneThemeOptions?: SceneThemeOptions): PublishTheme {
return useMemo(() => publishTheme(sceneThemeOptions), [sceneThemeOptions]);
}
Expand All @@ -51,7 +56,7 @@ export function publishTheme(sceneThemeOptions?: SceneThemeOptions): PublishThem
const isBackgroundDark = isDark(options?.themeBackgroundColor);

return {
mask: isDark(options?.themeBackgroundColor) ? "#FFFFFF0D" : "#0000001A",
mask: mask(options?.themeBackgroundColor) || "rgba(255, 255, 255, 0.15)",
background: options.themeBackgroundColor,
mainText: options.themeTextColor,
select: options.themeSelectColor,
Expand Down

0 comments on commit b934851

Please sign in to comment.