Skip to content

Commit

Permalink
feat(web): Toggle Field (#651)
Browse files Browse the repository at this point in the history
  • Loading branch information
jashanbhullar authored Aug 31, 2023
1 parent 0eaeed2 commit b13b187
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 110 deletions.
53 changes: 53 additions & 0 deletions web/src/beta/components/Toggle/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { useArgs } from "@storybook/preview-api";
import { Meta, StoryObj } from "@storybook/react";
import { useCallback } from "react";

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

import Toggle, { Props } from ".";

const meta: Meta<typeof Toggle> = {
component: Toggle,
};

export default meta;

type Story = StoryObj<typeof Toggle>;

export const Default: Story = (args: Props) => {
const [_, updateArgs] = useArgs();

const handleChange = useCallback(
(checked: boolean) => updateArgs({ checked: !checked }),
[updateArgs],
);

return (
<Wrapper>
<div>
<Toggle {...args} onChange={handleChange} />
</div>
<div>
<Toggle {...args} checked={!args.checked} onChange={handleChange} />
</div>
<div>
<Toggle {...args} checked={!args.checked} disabled={true} onChange={handleChange} />
</div>
</Wrapper>
);
};

const Wrapper = styled.div`
display: flex;
flex-direction: column;
gap: 10%;
margin-left: 2rem;
margin-top: 2rem;
height: 300px;
`;

Default.args = {
checked: true,
disabled: false,
onChange: () => console.log("clicked"),
};
57 changes: 57 additions & 0 deletions web/src/beta/components/Toggle/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { useCallback } from "react";

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

export type Props = {
checked: boolean;
onChange: (checked: boolean) => void;
disabled?: boolean;
};

const Toggle: React.FC<Props> = ({ checked, onChange, disabled = false }) => {
const handleClick = useCallback(
() => !disabled && onChange(checked),
[checked, onChange, disabled],
);

return (
<Wrapper>
<Switch checked={checked} disabled={disabled} onClick={handleClick}>
<TopSlider checked={checked} />
</Switch>
</Wrapper>
);
};

export default Toggle;

const Wrapper = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
`;

const Switch = styled.label<{
checked: boolean;
disabled: boolean;
}>`
cursor: ${({ disabled }) => (!disabled ? "pointer" : "not-allowed")};
width: 24px;
height: 14px;
background: ${({ checked, theme }) => (checked ? theme.select.main : theme.secondary.main)};
border: 1px solid ${({ checked, theme }) => (checked ? theme.select.main : theme.secondary.main)};
border-radius: 12px;
opacity: ${({ disabled }) => (!disabled ? 1 : 0.5)};
transition: 0.4s;
`;

const TopSlider = styled.div<{
checked: boolean;
}>`
width: 14px;
height: 14px;
background: ${({ theme }) => theme.content.withBackground};
transition: 0.4s;
border-radius: 50%;
transform: ${({ checked }) => checked && "translateX(10px)"};
`;
10 changes: 10 additions & 0 deletions web/src/beta/components/fields/PropertyFields/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import TextInput from "@reearth/beta/components/fields/TextInput";
import { type Item } from "@reearth/services/api/propertyApi/utils";

import ColorField from "../ColorField";
import ToggleField from "../ToggleField";

import useHooks from "./hooks";

Expand All @@ -18,6 +19,7 @@ const PropertyFields: React.FC<Props> = ({ propertyId, item }) => {
{item?.schemaFields.map(sf => {
const isList = item && "items" in item;
const value = !isList ? item.fields.find(f => f.id === sf.id)?.value : sf.defaultValue;

return sf.type === "string" ? (
sf.ui === "color" ? (
<ColorField
Expand All @@ -40,6 +42,14 @@ const PropertyFields: React.FC<Props> = ({ propertyId, item }) => {
onChange={handlePropertyValueUpdate(item.schemaGroup, propertyId, sf.id, sf.type)}
/>
)
) : sf.type == "bool" ? (
<ToggleField
key={sf.id}
name={sf.name}
checked={value as boolean}
description={sf.description}
onChange={handlePropertyValueUpdate(item.schemaGroup, propertyId, sf.id, sf.type)}
/>
) : (
<p key={sf.id}>{sf.name} field</p>
);
Expand Down
91 changes: 0 additions & 91 deletions web/src/beta/components/fields/Toggle/index.tsx

This file was deleted.

67 changes: 67 additions & 0 deletions web/src/beta/components/fields/ToggleField/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { useArgs } from "@storybook/preview-api";
import { Meta, StoryObj } from "@storybook/react";
import { useCallback } from "react";

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

import ToggleField, { Props } from ".";

const meta: Meta<typeof ToggleField> = {
component: ToggleField,
};

export default meta;

type Story = StoryObj<typeof ToggleField>;

export const Default: Story = (args: Props) => {
const [_, updateArgs] = useArgs();

const handleChange = useCallback(
(checked: boolean) => updateArgs({ checked: !checked }),
[updateArgs],
);

return (
<Wrapper>
<div>
<ToggleField {...args} onChange={handleChange} />
</div>
<div>
<ToggleField
{...args}
name="Reverse Toggle"
description={"Invesere of above"}
checked={!args.checked}
onChange={handleChange}
/>
</div>
<div>
<ToggleField
{...args}
name="Disabled"
description="Disabled field"
disabled={true}
onChange={handleChange}
/>
</div>
</Wrapper>
);
};

const Wrapper = styled.div`
display: flex;
flex-direction: column;
gap: 10%;
margin-left: 2rem;
margin-top: 2rem;
height: 300px;
`;

Default.args = {
name: "Toggle Field",
description: "Sample description",
checked: true,
disabled: false,
onChange: () => console.log("clicked"),
};
17 changes: 17 additions & 0 deletions web/src/beta/components/fields/ToggleField/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Property from "@reearth/beta/components/fields";
import Toggle, { Props as ToggleProps } from "@reearth/beta/components/Toggle";

export type Props = {
name?: string;
description?: string;
} & ToggleProps;

const ToggleField: React.FC<Props> = ({ name, description, ...args }: Props) => {
return (
<Property name={name} description={description}>
<Toggle {...args} />
</Property>
);
};

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

import Button from "@reearth/beta/components/Button";
import ToggleButton from "@reearth/beta/components/fields/Toggle";
import ToggleField from "@reearth/beta/components/fields/ToggleField";
import Icon from "@reearth/beta/components/Icon";
import Modal from "@reearth/beta/components/Modal";
import Text from "@reearth/beta/components/Text";
Expand Down Expand Up @@ -172,10 +172,12 @@ const PublishModal: React.FC<Props> = ({
<ArrowIcon icon="arrowToggle" size={16} open={showOptions} />
</OptionsToggle>
<HideableSection showOptions={showOptions}>
<Wrapper>
<Subtitle size="body">{t("Search engine indexing")}</Subtitle>
<ToggleButton checked={searchIndex} onChange={handleSearchIndexChange} />
</Wrapper>
<ToggleField
name={t("Search engine indexing")}
description={t("Page will be available as result on search engines")}
checked={searchIndex}
onChange={handleSearchIndexChange}
/>
</HideableSection>
</>
) : (
Expand Down Expand Up @@ -244,9 +246,3 @@ const UrlText = styled(Text)`
const HideableSection = styled(Section)<{ showOptions?: boolean }>`
display: ${props => (props.showOptions ? null : "none")};
`;

const Wrapper = styled.div`
display: flex;
justify-content: space-between;
align-content: center;
`;
16 changes: 8 additions & 8 deletions web/src/beta/features/Editor/tabs/widgets/Nav/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEffect } from "react";

import Toggle from "@reearth/beta/components/fields/Toggle";
import Text from "@reearth/beta/components/Text";
import Toggle from "@reearth/beta/components/Toggle";
import SecondaryNav from "@reearth/beta/features/Editor/SecondaryNav";
import { useT } from "@reearth/services/i18n";
import { selectedWidgetAreaVar } from "@reearth/services/state";
Expand Down Expand Up @@ -37,12 +38,8 @@ const Nav: React.FC<Props> = ({
<StyledSecondaryNav>
<Devices selectedDevice={selectedDevice} onDeviceChange={onDeviceChange} />
<AlignSystem>
<Toggle
label={t("Align System")}
size="sm"
checked={!!showWidgetEditor}
onChange={onShowWidgetEditor}
/>
<Text size="body">{t("Align System")}</Text>
<Toggle checked={!!showWidgetEditor} onChange={onShowWidgetEditor} />
</AlignSystem>
</StyledSecondaryNav>
);
Expand All @@ -57,4 +54,7 @@ const StyledSecondaryNav = styled(SecondaryNav)`
padding-left: 8px;
`;

const AlignSystem = styled.div``;
const AlignSystem = styled.div`
display: flex;
gap: 10px;
`;
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 @@ -32,6 +32,7 @@ Embed Code: Embed Code
'* Please use this code if you want to embed your project into a webpage': '* Please use this code if you want to embed your project into a webpage'
more options: more options
Search engine indexing: Search engine indexing
Page will be available as result on search engines: ''
Your project will be unpublished.: Your project will be unpublished.
This means that anybody with the URL will become unable to view this project.: This means that anybody with the URL will become unable to view this project.
'**Warning**: This includes websites where this project is embedded.': '**Warning**: This includes websites where this project is embedded.'
Expand Down
Loading

0 comments on commit b13b187

Please sign in to comment.