From a460f779bc42ab4e04a01533e2c287d086524050 Mon Sep 17 00:00:00 2001 From: Mohammad Smadi Date: Tue, 14 May 2024 00:35:14 +0300 Subject: [PATCH] Add RadioGroup component to Inputs index --- .../Inputs/RadioGroup/RadioGroup.stories.tsx | 38 +++++++++++++ src/Components/Inputs/RadioGroup/index.tsx | 55 +++++++++++++++++++ src/Components/Inputs/RadioGroup/types.ts | 10 ++++ src/Components/Inputs/Select/types.ts | 4 +- src/Components/Inputs/index.ts | 1 + src/Components/Inputs/types.ts | 2 + 6 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 src/Components/Inputs/RadioGroup/RadioGroup.stories.tsx create mode 100644 src/Components/Inputs/RadioGroup/index.tsx create mode 100644 src/Components/Inputs/RadioGroup/types.ts diff --git a/src/Components/Inputs/RadioGroup/RadioGroup.stories.tsx b/src/Components/Inputs/RadioGroup/RadioGroup.stories.tsx new file mode 100644 index 00000000..59b0c6a5 --- /dev/null +++ b/src/Components/Inputs/RadioGroup/RadioGroup.stories.tsx @@ -0,0 +1,38 @@ +import { faker } from "@faker-js/faker"; +import { action } from "@storybook/addon-actions"; +import { useState } from "react"; + +import RadioGroup from "."; +import { OptionValue } from "../Select/types"; + +export default { + title: "Input/RadioGroup", + component: RadioGroup, + parameters: { + layout: "centered" + }, + argTypes: { + onChange: { action: "changed" } + } +}; + +const dummyRadios = Array(5) + .fill(0) + .map(() => ({ + value: Math.floor(Math.random() * 1000000), + label: faker.lorem.words(Math.floor(Math.random() * 10) + 1) + })); + +export const Default = () => { + const [value, setValue] = useState(1); + return ( + { + setValue(value); + action("onChange")(value); + }} + options={dummyRadios} + /> + ); +}; diff --git a/src/Components/Inputs/RadioGroup/index.tsx b/src/Components/Inputs/RadioGroup/index.tsx new file mode 100644 index 00000000..ecf672c1 --- /dev/null +++ b/src/Components/Inputs/RadioGroup/index.tsx @@ -0,0 +1,55 @@ +import classNames from "classnames"; +import { FC } from "react"; + +import InputError from "Components/Inputs/Common/InputError"; +import InputHeader from "Components/Inputs/Common/InputHeader"; + +import { Option, OptionValue } from "../Select/types"; +import { IRadioGroup } from "./types"; + +const RadioGroup: FC = ( + props = { + value: "", + onChange: () => null, + options: [] + } +) => { + const { value, onChange, inputWrapperClassName, options } = props; + + const handleChange = (value: OptionValue) => { + if (!onChange) { + throw new Error("💣 Input is missing onChange handler 💣"); + } + + onChange?.(value); + }; + + return ( +
+ +
+ {options?.map((option, index) => ( + + ))} +
+ {props.error && } +
+ ); +}; + +export default RadioGroup; diff --git a/src/Components/Inputs/RadioGroup/types.ts b/src/Components/Inputs/RadioGroup/types.ts new file mode 100644 index 00000000..8f94c250 --- /dev/null +++ b/src/Components/Inputs/RadioGroup/types.ts @@ -0,0 +1,10 @@ +import { Option, OptionValue } from "../Select/types"; + +export interface IRadioGroup { + name?: string; + value?: OptionValue; + onChange?: (value: OptionValue) => void; + inputWrapperClassName?: string; + error?: string; + options?: Option[]; +} diff --git a/src/Components/Inputs/Select/types.ts b/src/Components/Inputs/Select/types.ts index 2f127eb4..93647b24 100644 --- a/src/Components/Inputs/Select/types.ts +++ b/src/Components/Inputs/Select/types.ts @@ -1,7 +1,9 @@ import { PropsValue } from "react-select"; +export type OptionValue = string | number; + export type Option = { - value: string | number; + value: OptionValue; label: string; }; diff --git a/src/Components/Inputs/index.ts b/src/Components/Inputs/index.ts index eab285ff..155010cd 100644 --- a/src/Components/Inputs/index.ts +++ b/src/Components/Inputs/index.ts @@ -1,6 +1,7 @@ export { default as AsyncSelect } from "./AsyncSelect"; export { default as Checkbox } from "./Checkbox"; export { default as InputError } from "./Common/InputError"; +export { default as RadioGroup } from "./RadioGroup"; export { default as InputHeader } from "./Common/InputHeader"; export { default as DomainInput } from "./DomainInput"; export { default as ImageInput } from "./ImageInput"; diff --git a/src/Components/Inputs/types.ts b/src/Components/Inputs/types.ts index 106bd069..408db643 100644 --- a/src/Components/Inputs/types.ts +++ b/src/Components/Inputs/types.ts @@ -3,6 +3,7 @@ import * as CheckboxTypes from "./Checkbox/types"; import * as CommonTypes from "./Common/types"; import * as DomainInputTypes from "./DomainInput/types"; import * as InputTypes from "./Input/types"; +import * as RadioGroupTypes from "./RadioGroup/types"; import * as SelectTypes from "./Select/types"; import * as SwitchTypes from "./Switch/types"; import * as TextareaTypes from "./Textarea/types"; @@ -13,6 +14,7 @@ export { CheckboxTypes, CommonTypes, DomainInputTypes, + RadioGroupTypes, InputTypes, SelectTypes, SwitchTypes,