-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GC-30; (Feat) Add Radio and RadioGroup components
- Loading branch information
1 parent
a16f2f9
commit 5517fe9
Showing
13 changed files
with
205 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React, { useCallback } from 'react' | ||
import { useForm } from '../FormContext' | ||
import { Form } from '../Form' | ||
import { RadioGroup } from '../../ui' | ||
import { FormItemProps } from '../Item' | ||
import type { RadioGroupProps } from '../../ui/Radio/interfaces' | ||
import { InputComponentWithName } from '../interfaces' | ||
|
||
export interface RadioInputProps extends RadioGroupProps, FormItemProps { | ||
name: string | ||
} | ||
|
||
export const RadioInput: InputComponentWithName<React.FC<RadioInputProps>> = ({ | ||
name, | ||
label, | ||
required, | ||
columnSpan, | ||
...inputProps | ||
}) => { | ||
const { values, errors, options, setValues } = useForm() | ||
const value = values[name] | ||
const error = errors[name]?.[0] | ||
const opts = options[name] | ||
|
||
const onChange = useCallback((e) => { | ||
setValues((values: any) => ({ ...values, [name]: e.target.value })) | ||
}, []) | ||
|
||
return ( | ||
<Form.Item label={label} required={required} error={error} columnSpan={columnSpan}> | ||
<RadioGroup | ||
options={opts} | ||
{...inputProps} | ||
name={name} | ||
value={value} | ||
onChange={onChange} | ||
/> | ||
</Form.Item> | ||
) | ||
} | ||
|
||
RadioInput.inputName = 'RadioInput' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.radio__Group { | ||
> *:not(:last-of-type) { | ||
margin-right: var(--space-s); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import React, { forwardRef, memo } from 'react' | ||
import { Checkbox } from '../Checkbox/' | ||
import { RadioProps } from './interfaces' | ||
|
||
const InternalRadio: React.ForwardRefRenderFunction<HTMLInputElement, RadioProps> = ( | ||
{ children, ...restProps }, | ||
ref, | ||
) => { | ||
return ( | ||
<Checkbox ref={ref} type="radio" {...restProps}> | ||
{children} | ||
</Checkbox> | ||
) | ||
} | ||
|
||
const Radio = forwardRef<HTMLInputElement, RadioProps>(InternalRadio) | ||
export default memo(Radio) as typeof Radio |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import React, { forwardRef, memo, useCallback, useEffect, useState } from 'react' | ||
import cn from 'classnames' | ||
import Radio from './Radio' | ||
import { ChoiceChangeEvent } from '../Choice/interfaces' | ||
import { RadioGroupProps } from './interfaces' | ||
import styles from './Radio.module.scss' | ||
|
||
const InternalRadioGroup: React.ForwardRefRenderFunction<HTMLDivElement, RadioGroupProps> = ( | ||
props, | ||
ref, | ||
) => { | ||
const { | ||
options = [], | ||
defaultValue, | ||
onChange, | ||
className, | ||
style, | ||
disabled, | ||
value: valueFromProps, | ||
onMouseEnter, | ||
onMouseLeave, | ||
onFocus, | ||
onBlur, | ||
...restProps | ||
} = props | ||
|
||
const [value, setValue] = useState( | ||
typeof valueFromProps === 'undefined' ? defaultValue : valueFromProps, | ||
) | ||
|
||
useEffect(() => { | ||
if (valueFromProps !== undefined || value !== valueFromProps) { | ||
setValue(valueFromProps) | ||
} | ||
}, [valueFromProps]) | ||
|
||
const _onChange = useCallback( | ||
(e: ChoiceChangeEvent) => { | ||
setValue(e.target.value) | ||
|
||
onChange?.(e) | ||
}, | ||
[onChange], | ||
) | ||
|
||
let childrenNode: React.ReactNode | ||
|
||
if (options && options.length > 0) { | ||
childrenNode = options.map((option) => { | ||
if (typeof option === 'string' || typeof option === 'number') { | ||
return ( | ||
<Radio | ||
key={`radio-value-${option}`} | ||
disabled={disabled} | ||
value={option} | ||
defaultChecked={defaultValue == option} | ||
checked={value === option} | ||
type="radio" | ||
onChange={_onChange} | ||
{...restProps} | ||
> | ||
{option} | ||
</Radio> | ||
) | ||
} | ||
|
||
return ( | ||
<Radio | ||
key={`radio-value-${option.value}`} | ||
disabled={disabled} | ||
value={option.value} | ||
defaultChecked={defaultValue == option.value} | ||
checked={value === option.value} | ||
type="radio" | ||
onChange={_onChange} | ||
{...restProps} | ||
> | ||
{option.label} | ||
</Radio> | ||
) | ||
}) | ||
} | ||
|
||
return ( | ||
<div | ||
className={cn(styles.radio__Group, className)} | ||
style={style} | ||
onMouseEnter={onMouseEnter} | ||
onMouseLeave={onMouseLeave} | ||
onFocus={onFocus} | ||
onBlur={onBlur} | ||
ref={ref} | ||
> | ||
{childrenNode} | ||
</div> | ||
) | ||
} | ||
|
||
const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(InternalRadioGroup) | ||
export default memo(RadioGroup) as typeof RadioGroup |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { default as Radio } from './Radio' | ||
export { default as RadioGroup } from './RadioGroup' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { CheckboxProps } from '../Checkbox/interfaces' | ||
|
||
export interface RadioProps extends CheckboxProps {} | ||
|
||
export type RadioValueType = string | number | null | ||
|
||
export interface RadioOptionType { | ||
label: React.ReactNode | ||
value: RadioValueType | ||
} | ||
|
||
export interface RadioGroupProps | ||
extends Omit< | ||
RadioProps, | ||
'defaultChecked' | 'checked' | 'type' | 'autofocus' | 'children' | 'id' | ||
> { | ||
options?: Array<RadioOptionType | string | number> | ||
defaultValue?: any | ||
onMouseEnter?: React.MouseEventHandler<HTMLDivElement> | ||
onMouseLeave?: React.MouseEventHandler<HTMLDivElement> | ||
onFocus?: React.FocusEventHandler<HTMLDivElement> | ||
onBlur?: React.FocusEventHandler<HTMLDivElement> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters