Skip to content

Commit

Permalink
feat(web): basic structure of plugin playground (#1036)
Browse files Browse the repository at this point in the history
  • Loading branch information
airslice authored Jul 1, 2024
1 parent c63cb53 commit 0fe2618
Show file tree
Hide file tree
Showing 17 changed files with 262 additions and 53 deletions.
2 changes: 1 addition & 1 deletion web/src/beta/features/Editor/Map/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const Map: FC = () => {
<LayersPanel />
</Area>
<Area direction="column" extend asWrapper>
<Area height={34}>
<Area initialHeight={34}>
<ToolsPanel />
</Area>
<Area extend onResize={handleVisualizerResize} windowRef={windowRef} passive />
Expand Down
2 changes: 1 addition & 1 deletion web/src/beta/features/Editor/Publish/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const Publish: FC = () => {
<Window ref={windowRef}>
<Area extend asWrapper>
<Area direction="column" extend asWrapper>
<Area height={34}>
<Area initialHeight={34}>
<PublishToolsPanel />
</Area>
<Area extend onResize={handleVisualizerResize} windowRef={windowRef} passive />
Expand Down
2 changes: 1 addition & 1 deletion web/src/beta/features/Editor/Widgets/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Widgets: FC = () => {
<Window ref={windowRef}>
<Area extend asWrapper>
<Area direction="column" extend asWrapper>
<Area height={34}>
<Area initialHeight={34}>
<WASToolsPanel />
</Area>
<Area extend onResize={handleVisualizerResize} windowRef={windowRef} passive />
Expand Down
7 changes: 7 additions & 0 deletions web/src/beta/features/PluginPlayground/Console/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { FC } from "react";

const Console: FC = () => {
return <div>Console content</div>;
};

export default Console;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { FC } from "react";

const PluginInspector: FC = () => {
return <div>Plugin inspector content</div>;
};

export default PluginInspector;
7 changes: 7 additions & 0 deletions web/src/beta/features/PluginPlayground/Plugins/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { FC } from "react";

const Plugins: FC = () => {
return <div>Plugins content</div>;
};

export default Plugins;
44 changes: 44 additions & 0 deletions web/src/beta/features/PluginPlayground/Viewer/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { useEffect, useMemo, useRef, useState } from "react";

import { Camera } from "@reearth/beta/utils/value";
import { MapRef } from "@reearth/core";
import { config } from "@reearth/services/config";

export default () => {
// Refrence: hooks of Editor/Visualizer/hooks.ts and Publish/hooks.ts
const visualizerRef = useRef<MapRef | null>(null);
const [ready, setReady] = useState(false);
const [currentCamera, setCurrentCamera] = useState<Camera | undefined>(undefined);

const engineMeta = useMemo(
() => ({
cesiumIonAccessToken: config()?.cesiumIonAccessToken,
}),
[],
);

const sceneProperty = useMemo(
() => ({
tiles: [
{
id: "default",
type: "default",
},
],
}),
[],
);

useEffect(() => {
setReady(true);
}, []);

return {
visualizerRef,
sceneProperty,
ready,
engineMeta,
currentCamera,
setCurrentCamera,
};
};
24 changes: 24 additions & 0 deletions web/src/beta/features/PluginPlayground/Viewer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { FC } from "react";

import Visualizer from "@reearth/beta/features/Visualizer";

import useHooks from "./hooks";

const Viewer: FC = () => {
const { visualizerRef, sceneProperty, ready, engineMeta, currentCamera, setCurrentCamera } =
useHooks();

return (
<Visualizer
engine="cesium"
visualizerRef={visualizerRef}
sceneProperty={sceneProperty}
ready={ready}
engineMeta={engineMeta}
currentCamera={currentCamera}
onCameraChange={setCurrentCamera}
/>
);
};

export default Viewer;
63 changes: 63 additions & 0 deletions web/src/beta/features/PluginPlayground/hooks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useMemo } from "react";

import { TabItem } from "@reearth/beta/lib/reearth-ui";

import Console from "./Console";
import PluginInspector from "./PluginInspector";
import Plugins from "./Plugins";
import Viewer from "./Viewer";

export default () => {
// Note: currently we put visualizer in tab content, so better not have more tabs in this area,
// otherwise visualizer will got unmount and mount when switching tabs.
const MainAreaTabs: TabItem[] = useMemo(
() => [
{
id: "viewer",
name: "Viewer",
children: <Viewer />,
},
],
[],
);

const BottomAreaTabs: TabItem[] = useMemo(
() => [
{
id: "console",
name: "Console",
children: <Console />,
},
],
[],
);

const SubRightAreaTabs: TabItem[] = useMemo(
() => [
{
id: "plugins",
name: "Plugins",
children: <Plugins />,
},
],
[],
);

const RightAreaTabs: TabItem[] = useMemo(
() => [
{
id: "plugin-inspector",
name: "Plugin Inspector",
children: <PluginInspector />,
},
],
[],
);

return {
MainAreaTabs,
BottomAreaTabs,
SubRightAreaTabs,
RightAreaTabs,
};
};
33 changes: 33 additions & 0 deletions web/src/beta/features/PluginPlayground/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { FC } from "react";

import { Tabs } from "@reearth/beta/lib/reearth-ui";
import { Area, Window } from "@reearth/beta/ui/layout";

import useHooks from "./hooks";

const PluginPlayground: FC = () => {
const { MainAreaTabs, BottomAreaTabs, SubRightAreaTabs, RightAreaTabs } = useHooks();

return (
<Window>
<Area extend asWrapper>
<Area direction="column" extend asWrapper>
<Area extend>
<Tabs position="top" tabs={MainAreaTabs} />
</Area>
<Area resizableEdge="top" initialHeight={100} storageId="plugin-playground-bottom-area">
<Tabs position="top" tabs={BottomAreaTabs} />
</Area>
</Area>
<Area direction="column" resizableEdge="left" storageId="plugin-playground-sub-right-area">
<Tabs position="top" tabs={SubRightAreaTabs} />
</Area>
<Area direction="column" resizableEdge="left" storageId="plugin-playground-right-area">
<Tabs position="top" tabs={RightAreaTabs} />
</Area>
</Area>
</Window>
);
};

export default PluginPlayground;
23 changes: 5 additions & 18 deletions web/src/beta/lib/reearth-ui/components/Tabs/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Meta, StoryObj } from "@storybook/react";
import { FC, useCallback, useState } from "react";
import { FC } from "react";

import { TabItems, Tabs as TabsMenu, TabsProps } from ".";
import { TabItem, Tabs as TabsMenu, TabsProps } from ".";

const meta: Meta<TabsProps> = {
component: TabsMenu,
Expand All @@ -12,23 +12,10 @@ export default meta;
type Story = StoryObj<TabsProps>;

const Tabs: FC<TabsProps> = ({ position, tabs, tabStyle }) => {
const [activeTab, setActiveTab] = useState("tab1");
const handleTabChange = useCallback((newTab: string) => {
setActiveTab(newTab);
}, []);

return (
<TabsMenu
position={position}
activeTab={activeTab}
tabStyle={tabStyle}
tabs={tabs}
onChange={handleTabChange}
/>
);
return <TabsMenu position={position} tabStyle={tabStyle} tabs={tabs} />;
};

const tabsItem: TabItems[] = [
const tabsItem: TabItem[] = [
{
id: "tab1",
name: "Tab One",
Expand All @@ -52,7 +39,7 @@ const tabsItem: TabItems[] = [
},
];

const tabsIcons: TabItems[] = [
const tabsIcons: TabItem[] = [
{
id: "tab1",
icon: "data",
Expand Down
34 changes: 27 additions & 7 deletions web/src/beta/lib/reearth-ui/components/Tabs/index.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,48 @@
import { FC, ReactNode, useMemo } from "react";
import { FC, ReactNode, useCallback, useEffect, useMemo, useState } from "react";

import { Icon, IconName, Typography } from "@reearth/beta/lib/reearth-ui";
import { styled, useTheme } from "@reearth/services/theme";

export type TabItems = {
export type TabItem = {
id: string;
name?: string;
icon?: IconName;
children?: ReactNode;
};

export type TabsProps = {
tabs: TabItems[];
tabs: TabItem[];
position?: "top" | "left";
tabStyle?: "normal" | "separated";
activeTab?: string;
currentTab?: string;
onChange?: (tab: string) => void;
};

export const Tabs: FC<TabsProps> = ({
tabs,
position = "top",
tabStyle = "normal",
activeTab,
currentTab,
onChange,
}) => {
const [activeTab, setActiveTab] = useState(currentTab ?? tabs[0].id);

const handleTabChange = useCallback(
(newTab: string) => {
setActiveTab(newTab);
onChange?.(newTab);
},
[onChange],
);

useEffect(() => {
if (currentTab) {
setActiveTab(currentTab);
}
}, [currentTab]);

const theme = useTheme();

const selectedTabItem = useMemo(() => {
return tabs.find(({ id }) => id === activeTab);
}, [activeTab, tabs]);
Expand All @@ -36,7 +53,7 @@ export const Tabs: FC<TabsProps> = ({
{tabs.map(({ id, icon, name }) => (
<Tab
key={id}
onClick={() => onChange?.(id)}
onClick={() => handleTabChange?.(id)}
selected={id === activeTab}
position={position}
tabStyle={tabStyle}>
Expand Down Expand Up @@ -67,6 +84,7 @@ const Wrapper = styled("div")<{ position?: "top" | "left" }>(({ position, theme
flexFlow: position === "top" ? "column nowrap" : "row nowrap",
background: theme.bg[1],
height: "100%",
width: "100%",
}));

const TabsMenu = styled("div")<{ position?: "top" | "left"; tabStyle?: "normal" | "separated" }>(
Expand Down Expand Up @@ -98,5 +116,7 @@ const Tab = styled("div")<{

const Content = styled("div")(({ theme }) => ({
padding: theme.spacing.normal,
height: "auto",
height: "100%",
width: "100%",
minHeight: 0,
}));
1 change: 1 addition & 0 deletions web/src/beta/lib/reearth-ui/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export * from "./IconButton";
export * from "./Selector";
export * from "./PopupMenu";
export * from "./DragAndDropList";
export * from "./Tabs";
9 changes: 9 additions & 0 deletions web/src/beta/pages/PluginPlaygroundPage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import PluginPlayground from "@reearth/beta/features/PluginPlayground";

type Props = {};

const PluginPlaygroundPage: React.FC<Props> = () => {
return <PluginPlayground />;
};

export default PluginPlaygroundPage;
Loading

0 comments on commit 0fe2618

Please sign in to comment.