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

refactor: use radio group in Data source manage #680

Merged
merged 20 commits into from
Sep 14, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export const Default: Story = (args: Props) => {
};

Default.args = {
label: "test",
inactive: false,
selected: false,
value: "test",
keyValue: "test",
};
44 changes: 20 additions & 24 deletions web/src/beta/components/RadioGroup/RadioBox/index.tsx
KaWaite marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,45 @@ import { fonts, styled } from "@reearth/services/theme";
export type Props = {
inactive?: boolean;
selected?: boolean;
value: string;
keyValue: string;
onClick?: (value: string) => void;
label?: string;
};

const RadioBox: React.FC<Props> = ({ inactive, selected, value, onClick }: Props) => {
const [isChecked, setIsChecked] = useState(selected ?? false);
const RadioBox: React.FC<Props> = ({ selected, keyValue, label, onClick }: Props) => {
const [isChecked, setIsChecked] = useState(!!selected);
KaWaite marked this conversation as resolved.
Show resolved Hide resolved

const handleRadioClick = useCallback(() => {
setIsChecked(!isChecked);
if (onClick) onClick(value);
}, [isChecked, onClick, value]);
const handleRadioClick = useCallback(
(value: string) => {
setIsChecked(!isChecked);
onClick?.(value);
},
[isChecked, 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={keyValue} onClick={() => handleRadioClick(keyValue)} />
<RadioButton selected={isChecked}>
{isChecked && <RadioIndicator selected={isChecked} />}
</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 +65,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
36 changes: 20 additions & 16 deletions web/src/beta/components/RadioGroup/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import RadioBox from "@reearth/beta/components/RadioGroup/RadioBox";
import { styled } from "@reearth/services/theme";

export type Option = {
KaWaite marked this conversation as resolved.
Show resolved Hide resolved
key: string;
value: string;
selected: boolean;
label?: string;
keyValue: string;
};

export type RadioGroupProps = {
Expand All @@ -16,38 +15,43 @@ export type RadioGroupProps = {
};

const RadioGroup: React.FC<RadioGroupProps> = ({ options, layout, onChange }) => {
const [currentOptions, updateOptions] = useState<Option[]>(options);
const [key, setKey] = useState(0);
nina992 marked this conversation as resolved.
Show resolved Hide resolved
const [selectedValue, setSelectedValue] = useState<string | undefined>(
options.length > 0 ? options[0].keyValue : undefined,
);

const handleRadioChange = useCallback(
(value: string) => {
updateOptions(
currentOptions.map(option => ({
...option,
selected: !option.selected && option.value === value,
})),
);
if (value === selectedValue) {
return; // Prevent deselecting the option
}
nina992 marked this conversation as resolved.
Show resolved Hide resolved

setKey(prevKey => prevKey + 1);
setSelectedValue(value);
onChange?.(value);
},
[currentOptions, onChange],
[onChange, selectedValue],
);

return (
<RadioGroupContainer layout={layout}>
{currentOptions.map(option => (
{options.map((option, index) => (
<RadioBox
key={`${option.key}-${key}`}
value={option.value}
selected={option.selected}
onClick={() => handleRadioChange(option.value)}
key={`${option.keyValue}-${key}-${index}`}
keyValue={option.keyValue}
selected={option.keyValue === selectedValue}
label={option.label || option.keyValue}
KaWaite marked this conversation as resolved.
Show resolved Hide resolved
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;
`;
27 changes: 9 additions & 18 deletions web/src/beta/features/Editor/DataSourceManager/Asset/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React 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 Down Expand Up @@ -78,22 +77,14 @@ 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={[
{ label: t("From URL"), keyValue: "url" },
{ label: t("From Value"), keyValue: "value" },
]}
layout="horizontal"
KaWaite marked this conversation as resolved.
Show resolved Hide resolved
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" }]}
layout="horizontal"
KaWaite marked this conversation as resolved.
Show resolved Hide resolved
onChange={setSourceType}
/>
</SourceTypeWrapper>
</InputGroup>
<InputGroup label="Resource URL" description="URL of the data source you want to add.">
Expand Down
Loading