Skip to content

Commit

Permalink
refactor: use radio group in Data source manage (#680)
Browse files Browse the repository at this point in the history
Co-authored-by: nina992 <[email protected]>
Co-authored-by: KaWaite <[email protected]>
  • Loading branch information
3 people authored Sep 14, 2023
1 parent 884b763 commit 72a00bf
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 81 deletions.
4 changes: 2 additions & 2 deletions web/src/beta/components/RadioGroup/RadioBox/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const Default: Story = (args: Props) => {
};

Default.args = {
inactive: false,
label: "test",
selected: false,
value: "test",
key: "test",
};
46 changes: 19 additions & 27 deletions web/src/beta/components/RadioGroup/RadioBox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,45 @@
import { useCallback, useState } from "react";
import { useCallback } from "react";

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

export type Props = {
inactive?: boolean;
selected?: boolean;
value: string;
key: string;
onClick?: (value: string) => void;
label?: string;
};

const RadioBox: React.FC<Props> = ({ inactive, selected, value, onClick }: Props) => {
const [isChecked, setIsChecked] = useState(selected ?? false);

const handleRadioClick = useCallback(() => {
setIsChecked(!isChecked);
if (onClick) onClick(value);
}, [isChecked, onClick, value]);
const RadioBox: React.FC<Props> = ({ selected, key, label, onClick }: Props) => {
const handleRadioClick = useCallback(
(value: string) => {
onClick?.(value);
},
[onClick],
);

return (
<Radio selected={isChecked} inactive={inactive}>
<RadioInput type="radio" value={inactive ? undefined : value} onClick={handleRadioClick} />
<RadioButton selected={isChecked} inactive={inactive}>
{isChecked && <Checkmark selected={isChecked} inactive={inactive} />}
<Radio>
<RadioInput type="radio" value={key} onClick={() => handleRadioClick(key)} />
<RadioButton selected={selected}>
{selected && <RadioIndicator selected={selected} />}
</RadioButton>
<RadioText>{value}</RadioText>
<RadioText>{label}</RadioText>
</Radio>
);
};
export default RadioBox;

const Checkmark = styled.div<{
inactive?: boolean;
const RadioIndicator = styled.div<{
selected?: boolean;
}>`
width: 10px;
height: 10px;
border-radius: 50%;
background-color: white;
background-color: ${({ selected, inactive, theme }) =>
selected ? theme.select.main : inactive ? theme.content.weaker : theme.content.main};
background-color: ${({ selected, theme }) => (selected ? theme.select.main : theme.content.main)};
`;

const Radio = styled.label<{
inactive?: boolean;
selected?: boolean;
}>`
const Radio = styled.label`
display: flex;
align-items: center;
min-width: 30px;
Expand All @@ -66,15 +61,12 @@ const RadioInput = styled.input`
`;

const RadioButton = styled.span<{
inactive?: boolean;
selected?: boolean;
}>`
width: 16px;
height: 16px;
border-radius: 50%;
border: 2px solid
${({ selected, inactive, theme }) =>
selected ? theme.select.main : inactive ? theme.content.weaker : theme.content.main};
border: 2px solid ${({ selected, theme }) => (selected ? theme.select.main : theme.content.main)};
margin-right: 4px;
display: flex;
justify-content: center;
Expand Down
4 changes: 2 additions & 2 deletions web/src/beta/components/RadioGroup/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export default meta;
type Story = StoryObj<typeof RadioGroup>;

const options = [
{ key: "option1", value: "Option 1", selected: false },
{ key: "option2", value: "Option 2", selected: false },
{ label: "option1", keyValue: "Option 1" },
{ label: "option2", keyValue: "Option 2" },
];

export const VerticalRadioGroup: Story = (args: Props) => {
Expand Down
41 changes: 20 additions & 21 deletions web/src/beta/components/RadioGroup/index.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,52 @@
import { memo, useCallback, useState } from "react";
import { memo, useCallback } from "react";

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

export type Option = {
key: string;
value: string;
selected: boolean;
label?: string;
keyValue: string;
};

export type RadioGroupProps = {
options: Option[];
layout?: "vertical" | "horizontal";
selectedValue?: string;
onChange?: (value: string) => void;
};

const RadioGroup: React.FC<RadioGroupProps> = ({ options, layout, onChange }) => {
const [currentOptions, updateOptions] = useState<Option[]>(options);
const [key, setKey] = useState(0);

const RadioGroup: React.FC<RadioGroupProps> = ({
options,
layout = "horizontal",
selectedValue,
onChange,
}) => {
const handleRadioChange = useCallback(
(value: string) => {
updateOptions(
currentOptions.map(option => ({
...option,
selected: !option.selected && option.value === value,
})),
);
setKey(prevKey => prevKey + 1);
if (value === selectedValue) return;
onChange?.(value);
},
[currentOptions, onChange],
[onChange, selectedValue],
);

return (
<RadioGroupContainer layout={layout}>
{currentOptions.map(option => (
{options.map(option => (
<RadioBox
key={`${option.key}-${key}`}
value={option.value}
selected={option.selected}
onClick={() => handleRadioChange(option.value)}
key={option.keyValue}
selected={option.keyValue === selectedValue}
label={option.label}
onClick={() => handleRadioChange(option.keyValue)}
/>
))}
</RadioGroupContainer>
);
};

export default memo(RadioGroup);

const RadioGroupContainer = styled.div<{ layout?: "vertical" | "horizontal" }>`
display: flex;
flex-direction: ${({ layout }) => (layout === "vertical" ? "column" : "row")};
gap: 12px;
`;
34 changes: 15 additions & 19 deletions web/src/beta/features/Editor/DataSourceManager/Asset/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from "react";
import React, { useMemo } from "react";

import Button from "@reearth/beta/components/Button";
import SelectField from "@reearth/beta/components/fields/SelectField";
import RadioGroup from "@reearth/beta/components/RadioGroup";
import Toggle from "@reearth/beta/components/Toggle";
import generateRandomString from "@reearth/beta/utils/generate-random-string";
import RadioButton from "@reearth/classic/components/atoms/RadioButton";
import { useT } from "@reearth/services/i18n";

import { DataProps } from "..";
Expand All @@ -14,7 +14,6 @@ import {
InputGroup,
Input,
SourceTypeWrapper,
RadioButtonLabel,
SubmitWrapper,
TextArea,
} from "../utils";
Expand All @@ -24,6 +23,7 @@ const SelectDataType: React.FC<{ fileFormat: string; setFileFormat: (k: string)
setFileFormat,
}) => {
const t = useT();

return (
<SelectField
value={fileFormat}
Expand All @@ -41,6 +41,13 @@ const Asset: React.FC<DataProps> = ({ sceneId, onSubmit, onClose }) => {
const [fileFormat, setFileFormat] = React.useState("GeoJSON");
const [value, setValue] = React.useState("");
const [prioritizePerformance, setPrioritizePerformance] = React.useState(false);
const DataSourceOptions = useMemo(
() => [
{ label: t("From URL"), keyValue: "url" },
{ label: t("From Value"), keyValue: "value" },
],
[t],
);

const handleSubmit = () => {
onSubmit({
Expand Down Expand Up @@ -78,22 +85,11 @@ const Asset: React.FC<DataProps> = ({ sceneId, onSubmit, onClose }) => {
label={t("Source Type")}
description={t("Select the type of data source you want to add.")}>
<SourceTypeWrapper>
<RadioButtonLabel>
<RadioButton
value="url"
checked={sourceType == "url"}
handleChange={c => c && setSourceType("url")}
/>
{t("From URL")}
</RadioButtonLabel>
<RadioButtonLabel>
<RadioButton
value="value"
checked={sourceType == "value"}
handleChange={c => c && setSourceType("value")}
/>
{t("From Value")}
</RadioButtonLabel>
<RadioGroup
options={DataSourceOptions}
selectedValue={sourceType}
onChange={setSourceType}
/>
</SourceTypeWrapper>
</InputGroup>
{sourceType == "url" && (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from "react";

import Button from "@reearth/beta/components/Button";
import RadioGroup from "@reearth/beta/components/RadioGroup";
import Text from "@reearth/beta/components/Text";
import generateRandomString from "@reearth/beta/utils/generate-random-string";
import RadioButton from "@reearth/classic/components/atoms/RadioButton";
import { useT } from "@reearth/services/i18n";

import { DataProps } from "..";
import {
Expand All @@ -13,10 +14,11 @@ import {
Input,
SourceTypeWrapper,
SubmitWrapper,
RadioButtonLabel,
} from "../utils";

const DelimitedText: React.FC<DataProps> = ({ sceneId, onSubmit, onClose }) => {
const t = useT();

const [sourceType, setSourceType] = React.useState("url"); // ["url", "local", "value"]
const [value, setValue] = React.useState("");
const [lat, setLat] = React.useState("");
Expand Down Expand Up @@ -61,14 +63,11 @@ const DelimitedText: React.FC<DataProps> = ({ sceneId, onSubmit, onClose }) => {
label="Source Type"
description="Select the type of data source you want to add.">
<SourceTypeWrapper>
<RadioButtonLabel>
<RadioButton
value="url"
checked={sourceType == "url"}
handleChange={c => c && setSourceType("url")}
/>
From URL
</RadioButtonLabel>
<RadioGroup
options={[{ label: t("From URL"), keyValue: "url" }]}
selectedValue={sourceType}
onChange={setSourceType}
/>
</SourceTypeWrapper>
</InputGroup>
<InputGroup label="Resource URL" description="URL of the data source you want to add.">
Expand Down

0 comments on commit 72a00bf

Please sign in to comment.