Skip to content

Commit

Permalink
chore(web): move visualizer to beta (#460)
Browse files Browse the repository at this point in the history
  • Loading branch information
keiya01 committed Jun 2, 2023
1 parent ef30ad0 commit 5ed8195
Show file tree
Hide file tree
Showing 340 changed files with 37,820 additions and 15 deletions.
12 changes: 12 additions & 0 deletions web/src/beta/components/AdditionButton/index.stories.tsx
@@ -0,0 +1,12 @@
import { Story, Meta } from "@storybook/react";
import { Component } from "react";

import AdditionButton, { Props } from ".";

export default {
component: AdditionButton,
} as Meta;

export const Default: Story<Props> = args => <Component {...args} />;

Default.args = {};
109 changes: 109 additions & 0 deletions web/src/beta/components/AdditionButton/index.tsx
@@ -0,0 +1,109 @@
import React, { useRef, useCallback, useEffect } from "react";
import { usePopper } from "react-popper";

import Icon from "@reearth/beta/components/Icon";
import { styled } from "@reearth/services/theme";

import Portal from "../Portal";

export interface Props {
className?: string;
disabled?: boolean;
onClick?: () => void;
children?: React.ReactNode;
}

const AdditionButton: React.FC<Props> = ({ className, children, disabled, onClick }) => {
const referenceElement = useRef<HTMLDivElement>(null);
const popperElement = useRef<HTMLDivElement>(null);
const {
styles,
attributes,
update: updatePopper,
} = usePopper(referenceElement.current, popperElement.current, {
placement: "bottom",
strategy: "fixed",
modifiers: [
{
name: "eventListeners",
enabled: false,
options: {
scroll: false,
resize: false,
},
},
],
});

const handleClick = useCallback(() => {
if (disabled) return;
onClick?.();
}, [disabled, onClick]);

// TODO: わかりずらい。もっといい方法ありそう。
useEffect(() => {
if (children) {
updatePopper?.();
}
}, [children, updatePopper]);

return (
<Wrapper>
<InsertArea onClick={handleClick}>
<Line />
<Button className={className} ref={referenceElement}>
<StyledIcon icon="plusSquare" size={13} />
</Button>
<Line />
</InsertArea>
<Portal>
<div ref={popperElement} style={{ ...styles.popper, zIndex: 1000 }} {...attributes.popper}>
{children}
</div>
</Portal>
</Wrapper>
);
};

const Wrapper = styled.div`
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:hover {
* {
visibility: visible;
opacity: 1;
}
}
`;

const InsertArea = styled.div`
width: 100%;
padding: 0 0 30px 0;
display: flex;
align-items: center;
justify-content: center;
visibility: hidden;
opacity: 0;
transition: all 0.5s;
`;

const StyledIcon = styled(Icon)`
color: ${props => props.theme.infoBox.accent};
`;

const Button = styled.div`
color: ${props => props.theme.infoBox.accent};
margin: 0 3px;
`;

const Line = styled.div`
width: 43%;
background-color: ${props => props.theme.main.accent};
height: 2px;
margin-top: -2px;
`;

export default AdditionButton;
11 changes: 11 additions & 0 deletions web/src/beta/components/ContentPicker/README.md
@@ -0,0 +1,11 @@
# Contents Picker
[![Generic badge](https://img.shields.io/badge/GROUP-infobox-blue.svg)]()
[![Generic badge](https://img.shields.io/badge/SIZE-molecules-orange.svg)]()

Contents Picker Modal for InfoBox

## Usage

## Properties

## Screenshots
9 changes: 9 additions & 0 deletions web/src/beta/components/ContentPicker/index.stories.tsx
@@ -0,0 +1,9 @@
import { Meta } from "@storybook/react";

import ContentPicker from ".";

export default {
component: ContentPicker,
} as Meta;

export const Default = () => <ContentPicker />;
115 changes: 115 additions & 0 deletions web/src/beta/components/ContentPicker/index.tsx
@@ -0,0 +1,115 @@
import React, { useRef } from "react";
import { useClickAway } from "react-use";

import Icon from "@reearth/beta/components/Icon";
import Text from "@reearth/beta/components/Text";
import { styled } from "@reearth/services/theme";

export interface Item {
id: string;
name: string;
icon?: string;
}

export interface ContentsPickerProps {
className?: string;
items?: Item[];
onClickAway?: () => void;
onSelect?: (index: number) => void;
}

const ContentPicker: React.FC<ContentsPickerProps> = ({
className,
items: items,
onSelect,
onClickAway,
}) => {
const ref = useRef(null);
useClickAway(ref, () => onClickAway?.());
return (
<Wrapper className={className} ref={ref}>
<ContentsList>
{items?.map((item, i) => (
<ContentItem key={item.id}>
<ContentButton onClick={() => onSelect?.(i)}>
<StyledIcon icon={item.icon} size={20} />
<ButtonText size="xs">{item.name}</ButtonText>
</ContentButton>
</ContentItem>
))}
{new Array((items ?? []).length % 3).fill(undefined).map((_, i) => (
<GhostButton key={i} />
))}
</ContentsList>
</Wrapper>
);
};

const Wrapper = styled.div`
background: ${props => props.theme.infoBox.bg};
margin-top: 5px;
padding: 10px;
box-sizing: border-box;
border-radius: 3px;
width: 288px;
color: ${props => props.theme.infoBox.mainText};
box-shadow: 0 0 5px ${props => props.theme.infoBox.deepBg};
&:after {
content: "";
position: absolute;
right: 0;
top: -5px;
left: 0;
width: 0px;
height: 0px;
margin: auto;
border-style: solid;
border-color: transparent transparent ${props => props.theme.infoBox.bg} transparent;
border-width: 0 10px 10px 10px;
}
`;

const ContentsList = styled.div`
display: flex;
flex-wrap: wrap;
height: 100%;
max-height: 200px;
overflow: auto;
`;

const ContentItem = styled.div`
flex: 0 0 33.33333%;
display: flex;
align-items: center;
justify-content: center;
`;

const ContentButton = styled.div`
padding: 5px;
width: 60px;
border: solid 0.5px transparent;
box-sizing: border-box;
text-align: center;
cursor: pointer;
&:hover {
border-radius: 6px;
border: solid 0.5px ${props => props.theme.main.select};
}
`;

const GhostButton = styled.div`
width: 30%;
`;

const ButtonText = styled(Text)`
margin: 3px 0;
user-select: none;
`;

const StyledIcon = styled(Icon)`
display: block;
margin: 0 auto;
`;

export default ContentPicker;
39 changes: 39 additions & 0 deletions web/src/beta/components/DropHolder/index.tsx
@@ -0,0 +1,39 @@
import React from "react";

import { useT } from "@reearth/services/i18n";
import { styled } from "@reearth/services/theme";

export interface Props {
className?: string;
}

const DropHolder: React.FC<Props> = ({ className }) => {
const t = useT();

return (
<DraggableView className={className}>
<DragMessage>{t("Drop here")}</DragMessage>
</DraggableView>
);
};

const DraggableView = styled.div`
position: absolute;
z-index: ${props => props.theme.zIndexes.dropDown};
top: 0;
left: 0;
width: 100%;
height: 100%;
background: ${props => props.theme.main.accent};
opacity: 0.5;
display: flex;
align-items: center;
justify-content: center;
`;

const DragMessage = styled.p`
color: ${props => props.theme.main.text};
opacity: 1;
`;

export default DropHolder;
10 changes: 10 additions & 0 deletions web/src/beta/components/Filled/index.ts
@@ -0,0 +1,10 @@
import { styled } from "@reearth/services/theme";

const Filled = styled.div`
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
`;

export default Filled;
43 changes: 43 additions & 0 deletions web/src/beta/components/Flex/index.stories.tsx
@@ -0,0 +1,43 @@
import { Meta, Story } from "@storybook/react";

import Component, { Props } from ".";

export default {
component: Component,
} as Meta;

const ExampleDiv = () => (
<>
<div>hoge</div>
<div>fuga</div>
</>
);

export const SpaceBetween: Story<Props> = args => (
<Component {...args}>
<ExampleDiv />
</Component>
);
export const GapChildren: Story<Props> = args => (
<Component {...args}>
<div>hoge</div>
<div>fuga</div>
</Component>
);
export const DirectionVertical: Story<Props> = args => (
<Component {...args}>
<ExampleDiv />
</Component>
);

SpaceBetween.args = {
justify: "space-between",
};

GapChildren.args = {
gap: "20px",
};

DirectionVertical.args = {
direction: "column",
};

0 comments on commit 5ed8195

Please sign in to comment.