Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(web): add container settings panel for widget area #620

Merged
merged 9 commits into from
Aug 10, 2023
18 changes: 10 additions & 8 deletions web/src/beta/components/SidePanelSectionField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@ import Icon from "../Icon";
import Text from "../Text";

const SidePanelSectionField: React.FC<{
title: string;
title?: string;
children?: ReactNode;
}> = ({ title, children }) => {
const theme = useTheme();
const [opened, setOpened] = useState(true);

return (
<Field>
<Header onClick={() => setOpened(!opened)}>
<Text size="body" color={theme.content.main}>
{title}
</Text>
<ArrowIcon icon="arrowToggle" size={12} color={theme.content.main} opened={opened} />
</Header>
{title && (
<Header onClick={() => setOpened(!opened)}>
<Text size="body" color={theme.content.main}>
{title}
</Text>
<ArrowIcon icon="arrowToggle" size={12} color={theme.content.main} opened={opened} />
</Header>
)}
{opened && children && <Content>{children}</Content>}
</Field>
);
Expand All @@ -45,7 +47,7 @@ const ArrowIcon = styled(Icon)<{ opened: boolean }>`
`;

const Content = styled.div`
padding: 0 8px 8px 8px;
padding: 8px;
display: flex;
flex-direction: column;
gap: 4px;
Expand Down
12 changes: 8 additions & 4 deletions web/src/beta/features/Editor/Visualizer/CanvasArea/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useReactiveVar } from "@apollo/client";
import { useMemo, useEffect, useCallback, useState } from "react";

import type { Alignment, Location } from "@reearth/beta/lib/core/Crust";
Expand All @@ -13,7 +14,7 @@
useSelectedBlock,
useWidgetAlignEditorActivated,
useZoomedLayerId,
useSelectedWidgetArea,
selectedWidgetAreaVar,
} from "@reearth/services/state";

import { convertWidgets } from "./convert";
Expand All @@ -29,7 +30,7 @@
const [camera, onCameraChange] = useCamera();
const [selected, select] = useSelected();
const [selectedBlock, selectBlock] = useSelectedBlock();
const [selectedWidgetArea, selectWidgetArea] = useSelectedWidgetArea();
const selectedWidgetArea = useReactiveVar(selectedWidgetAreaVar);
const [widgetAlignEditorActivated] = useWidgetAlignEditorActivated();
const [zoomedLayerId, zoomToLayer] = useZoomedLayerId();

Expand Down Expand Up @@ -92,7 +93,7 @@

const widgets = convertWidgets(scene);
// TODO: Fix to use exact type through GQL typing
const sceneProperty: any = useMemo(

Check warning on line 96 in web/src/beta/features/Editor/Visualizer/CanvasArea/hooks.ts

View workflow job for this annotation

GitHub Actions / ci-web / ci

Unexpected any. Specify a different type
() => ({
tiles: [
{
Expand Down Expand Up @@ -129,7 +130,7 @@
vt: T,
selectedLayer?: Layer,
) => {
const propertyId = (selectedLayer?.infobox?.blocks?.find(b => b.id === blockId) as any)

Check warning on line 133 in web/src/beta/features/Editor/Visualizer/CanvasArea/hooks.ts

View workflow job for this annotation

GitHub Actions / ci-web / ci

Unexpected any. Specify a different type
?.propertyId as string | undefined;
if (!propertyId) return;

Expand Down Expand Up @@ -182,7 +183,10 @@

const onWidgetAlignSystemUpdate = useCallback(
async (location: Location, align: Alignment) => {
await useUpdateWidgetAlignSystem(location, align, sceneId);
await useUpdateWidgetAlignSystem(
{ zone: location.zone, section: location.section, area: location.area, align },
sceneId,
);
},
[sceneId, useUpdateWidgetAlignSystem],
);
Expand Down Expand Up @@ -227,7 +231,7 @@
onBlockRemove,
onBlockInsert,
onWidgetUpdate,
selectWidgetArea,
selectWidgetArea: selectedWidgetAreaVar,
KaWaite marked this conversation as resolved.
Show resolved Hide resolved
onWidgetAlignSystemUpdate,
onIsCapturingChange,
onCameraChange,
Expand Down
10 changes: 10 additions & 0 deletions web/src/beta/features/Editor/tabs/widgets/Nav/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { useEffect } from "react";

import Toggle from "@reearth/beta/components/properties/Toggle";
import SecondaryNav from "@reearth/beta/features/Editor/SecondaryNav";
import { useT } from "@reearth/services/i18n";
import { selectedWidgetAreaVar } from "@reearth/services/state";
import { styled } from "@reearth/services/theme";

import Devices, { type Device } from "./Devices";
Expand All @@ -23,6 +26,13 @@ const Nav: React.FC<Props> = ({
onDeviceChange,
}) => {
const t = useT();

useEffect(() => {
if (!showWidgetEditor) {
selectedWidgetAreaVar(undefined);
}
}, [showWidgetEditor]);

return (
<StyledSecondaryNav>
<Devices selectedDevice={selectedDevice} onDeviceChange={onDeviceChange} />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import TextInput from "@reearth/beta/components/properties/TextInput";
import SidePanelSectionField from "@reearth/beta/components/SidePanelSectionField";
import { WidgetAreaPadding, WidgetAreaState } from "@reearth/services/state";

type Props = {
widgetArea: WidgetAreaState;
onWidgetAreaStateChange: (widgetArea: WidgetAreaState) => void;
};

const ContainerSettings: React.FC<Props> = ({ widgetArea, onWidgetAreaStateChange }) => {
// TODO: This is dummy UI
return (
<SidePanelSectionField>
<TextInput
name="Padding Top"
value={widgetArea?.padding?.top.toString()}
onChange={newVal => {
onWidgetAreaStateChange({
...widgetArea,
padding: {
...(widgetArea.padding as WidgetAreaPadding),
top: Number(newVal) ?? 0,
},
});
}}
/>
<TextInput
name="Padding Right"
value={widgetArea?.padding?.right.toString()}
onChange={newVal => {
onWidgetAreaStateChange({
...widgetArea,
padding: {
...(widgetArea.padding as WidgetAreaPadding),
right: Number(newVal) ?? 0,
},
});
}}
/>
<TextInput
name="Padding Bottom"
value={widgetArea?.padding?.bottom.toString()}
onChange={newVal => {
onWidgetAreaStateChange({
...widgetArea,
padding: {
...(widgetArea.padding as WidgetAreaPadding),
bottom: Number(newVal) ?? 0,
},
});
}}
/>
<TextInput
name="Padding Left"
value={widgetArea?.padding?.left.toString()}
onChange={newVal => {
onWidgetAreaStateChange({
...widgetArea,
padding: {
...(widgetArea.padding as WidgetAreaPadding),
left: Number(newVal) ?? 0,
},
});
}}
/>

<TextInput
name="Gap Spacing"
value={(widgetArea?.gap ?? 0).toString()}
onChange={newVal => {
onWidgetAreaStateChange({
...widgetArea,
gap: Number(newVal) ?? 0,
});
}}
/>

<div>[Switch field] Align Center {!!widgetArea?.centered}</div>
<div>[Color field] Background Color {widgetArea?.background}</div>
</SidePanelSectionField>
);
};

export default ContainerSettings;
29 changes: 26 additions & 3 deletions web/src/beta/features/Editor/tabs/widgets/SidePanel/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,25 @@ import { useReactiveVar } from "@apollo/client";
import { useCallback, useMemo } from "react";

import { useWidgetsFetcher } from "@reearth/services/api";
import { selectedWidgetVar } from "@reearth/services/state";
import {
selectedWidgetVar,
selectedWidgetAreaVar,
type WidgetAreaState,
} from "@reearth/services/state";

export default ({ sceneId }: { sceneId?: string }) => {
const { useInstallableWidgetsQuery, useInstalledWidgetsQuery, useAddWidget, useRemoveWidget } =
useWidgetsFetcher();
const {
useInstallableWidgetsQuery,
useInstalledWidgetsQuery,
useAddWidget,
useRemoveWidget,
useUpdateWidgetAlignSystem,
} = useWidgetsFetcher();
const { installableWidgets } = useInstallableWidgetsQuery({ sceneId });
const { installedWidgets } = useInstalledWidgetsQuery({ sceneId });

const selectedWidget = useReactiveVar(selectedWidgetVar);
const selectedWidgetArea = useReactiveVar(selectedWidgetAreaVar);

const propertyItems = useMemo(
() => installedWidgets?.find(w => w.id === selectedWidget?.id)?.property.items,
Expand Down Expand Up @@ -47,13 +57,26 @@ export default ({ sceneId }: { sceneId?: string }) => {
[sceneId, useRemoveWidget],
);

const handleWidgetAreaStateChange = useCallback(
async (widgetAreaState?: WidgetAreaState) => {
if (!sceneId || !widgetAreaState) return;
const results = await useUpdateWidgetAlignSystem(widgetAreaState, sceneId);
if (results.status === "success") {
selectedWidgetAreaVar(widgetAreaState);
}
},
[sceneId, useUpdateWidgetAlignSystem],
);

return {
selectedWidget,
selectedWidgetArea,
propertyItems,
installedWidgets,
installableWidgets,
handleWidgetAdd,
handleWidgetRemove,
handleWidgetSelection,
handleWidgetAreaStateChange,
};
};
14 changes: 14 additions & 0 deletions web/src/beta/features/Editor/tabs/widgets/SidePanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import SidePanelCommon from "@reearth/beta/features/Editor/SidePanel";
import { useT } from "@reearth/services/i18n";

import ContainerSettings from "./ContainerSettings";
import useHooks from "./hooks";
import Manager, { ActionArea } from "./Manager";
import Settings from "./Settings";
Expand All @@ -15,12 +16,14 @@ const SidePanel: React.FC<Props> = ({ sceneId }) => {

const {
selectedWidget,
selectedWidgetArea,
propertyItems,
installedWidgets,
installableWidgets,
handleWidgetAdd,
handleWidgetRemove,
handleWidgetSelection,
handleWidgetAreaStateChange,
} = useHooks({ sceneId });

return (
Expand Down Expand Up @@ -51,6 +54,17 @@ const SidePanel: React.FC<Props> = ({ sceneId }) => {
<Settings widgetPropertyId={selectedWidget.propertyId} propertyItems={propertyItems} />
),
},
{
id: "containerSettings",
title: t("Container Settings"),
hide: !selectedWidgetArea,
children: selectedWidgetArea && sceneId && (
<ContainerSettings
widgetArea={selectedWidgetArea}
onWidgetAreaStateChange={handleWidgetAreaStateChange}
/>
),
},
]}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export default function Area({
editorStyle={{
flexWrap: "wrap",
padding: `${padding?.top}px ${padding?.right}px ${padding?.bottom}px ${padding?.left}px`,
background: backgroundColor
backgroundColor: backgroundColor
? backgroundColor
: area === "middle"
? theme.placeHolder.main_2
Expand Down
16 changes: 10 additions & 6 deletions web/src/services/api/widgetsApi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
UPDATE_WIDGET_ALIGN_SYSTEM,
} from "@reearth/services/gql/queries/widget";
import { useT } from "@reearth/services/i18n";
import { useNotification } from "@reearth/services/state";
import { WidgetAreaState, useNotification } from "@reearth/services/state";

import { SceneQueryProps } from "../sceneApi";
import { MutationReturn } from "../types";
Expand Down Expand Up @@ -196,7 +196,7 @@ export default () => {
});

const useUpdateWidgetAlignSystem = useCallback(
async (location: WidgetLocation, align: WidgetAlignment, sceneId?: string) => {
async (widgetAreaState: WidgetAreaState, sceneId?: string) => {
if (!sceneId) {
console.log(
"GraphQL: Failed to update the widget align system because there is no sceneId provided",
Expand All @@ -211,11 +211,15 @@ export default () => {
variables: {
sceneId,
location: {
zone: location.zone.toUpperCase() as WidgetZoneType,
section: location.section.toUpperCase() as WidgetSectionType,
area: location.area.toUpperCase() as WidgetAreaType,
zone: widgetAreaState.zone.toUpperCase() as WidgetZoneType,
section: widgetAreaState.section.toUpperCase() as WidgetSectionType,
area: widgetAreaState.area.toUpperCase() as WidgetAreaType,
},
align: align?.toUpperCase() as WidgetAreaAlign,
align: widgetAreaState.align?.toUpperCase() as WidgetAreaAlign,
background: widgetAreaState.background,
padding: widgetAreaState.padding,
centered: widgetAreaState.centered,
gap: widgetAreaState.gap,
},
});

Expand Down
1 change: 1 addition & 0 deletions web/src/services/i18n/translations/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Page: Page
Align System: Align System
Widget Manager: Widget Manager
Inspector: Inspector
Container Settings: Container Settings
Angle: Angle
Narrow: Narrow
Wide: Wide
Expand Down
1 change: 1 addition & 0 deletions web/src/services/i18n/translations/ja.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Page: ページ
Align System: アラインシステム
Widget Manager: ウィジェット管理
Inspector: インスペクター
Container Settings: Container Settings
airslice marked this conversation as resolved.
Show resolved Hide resolved
Angle: 角度
Narrow: 狭い
Wide: 広い
Expand Down
4 changes: 4 additions & 0 deletions web/src/services/state/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { makeVar } from "@apollo/client";

import type { WidgetAreaType } from "@reearth/beta/lib/core/Crust";

export type SelectedWidget = {
id: string;
pluginId: string;
Expand All @@ -9,4 +11,6 @@ export type SelectedWidget = {

export const selectedWidgetVar = makeVar<SelectedWidget | undefined>(undefined);

export const selectedWidgetAreaVar = makeVar<WidgetAreaType | undefined>(undefined);

export * from "./jotai";
Loading