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

Radio 컴포넌트 ESLint 적용 #99

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/radio/src/components/Radio.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/** @jsxImportSource @emotion/react */
import * as Style from '../styles';
import { useId, useContext, forwardRef } from 'react';
import { createClassVariant, getColorByTokenOrHex } from '@jdesignlab/theme';
import { getComponentText } from '@jdesignlab/react-utils';
import { RadioContext } from '../context';
import RadioGroup from './RadioGroup';
import RadioLabel from './RadioLabel';
import { RadioContext } from '../context';
import * as Style from '../styles';
import useRadio from '../hooks/useRadio';
import { DEFAULT_COLOR, DEFAULT_DISABLED_COLOR, RADIO_ID_PREFIX } from '../constants';
import validateEventHandlers from '../utils/validateEventHandlers';
Expand All @@ -26,6 +26,7 @@ export const Radio = Object.assign(
name = '',
...restProps
} = props;
const uuid = useId();
const radioContext = useContext(RadioContext);
const isUnavailable = !!readonly || !!disabled;
const validRadioProps = validateEventHandlers(isUnavailable, restProps, radioContext?.rootProps);
Expand All @@ -34,7 +35,7 @@ export const Radio = Object.assign(
validRadioProps,
radioContext?.setValue
);
const radioId = id ?? `${RADIO_ID_PREFIX}-${useId()}`;
const radioId = id ?? `${RADIO_ID_PREFIX}-${uuid}`;
const radioClassName = className
? `${createClassVariant('radio', 'wrapper')} ${className}`
: createClassVariant('radio', 'wrapper');
Expand Down
2 changes: 1 addition & 1 deletion packages/radio/src/components/RadioGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { RadioGroupProps } from '../types';

const RadioGroup = Object.assign(
forwardRef<HTMLInputElement, RadioGroupProps>((props: RadioGroupProps, ref) => {
const { children, defaultValue = null, ...restProps } = props;
const { children, defaultValue, ...restProps } = props;
const radioGroupRef = useRadioGroup(defaultValue, ref);

return (
Expand Down
2 changes: 1 addition & 1 deletion packages/radio/src/components/RadioLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @jsxImportSource @emotion/react */
import * as Style from '../styles';
import { createClassVariant } from '@jdesignlab/theme';
import * as Style from '../styles';
import { DEFAULT_FONT_COLOR } from '../constants';
import type { RadioLabelProps } from '../types';

Expand Down
40 changes: 24 additions & 16 deletions packages/radio/src/components/RadioProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
import type { ReactNode } from 'react';
import { useId, useMemo, useState } from 'react';
import { RadioContext } from '../context';
import { useId, useState } from 'react';
import { RADIO_NAME_PREFIX } from '../constants';
import type { RadioGroupProps, ReturnContext } from '../types';

export const RadioProvider = ({ ...props }) => {
const { children, defaultValue = null, rootProps = null } = props;
const defaultName = rootProps && rootProps.name ? rootProps.name : `${RADIO_NAME_PREFIX}_${useId()}`;
interface RadioProviderProps {
defaultValue?: string;
children: ReactNode;
rootProps?: RadioGroupProps;
}

export const RadioProvider = ({ ...props }: RadioProviderProps) => {
const { children, defaultValue, rootProps } = props;
const uuid = useId();
const defaultName = `${RADIO_NAME_PREFIX}_${uuid}`;
const [value, setValue] = useState<string>('');

return (
<RadioContext.Provider
value={{
setValue,
value,
defaultValue,
name: defaultName,
rootProps: { ...rootProps }
}}
>
{children}
</RadioContext.Provider>
const providerValue = useMemo(
() => ({
setValue,
value,
defaultValue,
name: defaultName,
rootProps: { ...rootProps }
}),
[value, setValue, defaultValue, defaultName, rootProps]
);

return <RadioContext.Provider value={providerValue as ReturnContext}>{children}</RadioContext.Provider>;
};
14 changes: 7 additions & 7 deletions packages/radio/src/hooks/useRadio.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { Dispatch, SetStateAction } from 'react';
import { ChangeEvent, useCallback, useRef, useState } from 'react';
import { RadioAttributes } from '../types';
import { callHandler } from '@jdesignlab/utils';
import { RadioProps } from '../types';
import type { EventType } from '@jdesignlab/utils';
import type { Dispatch, SetStateAction } from 'react';

const useRadio = (
isUnavailable: boolean,
radioProps: RadioAttributes,
radioProps: RadioProps,
contextSetValue?: Dispatch<SetStateAction<string>> | null
) => {
const [radioValue, setValue] = useState<string>('');
Expand All @@ -30,12 +30,12 @@ const useRadio = (

return propsOnKeyDown ? callHandler(defaultHandleKeydown, propsOnKeyDown) : defaultHandleKeydown;
},
[radioRef]
[contextSetValue, isUnavailable]
);

const combineChangeHandler = (propsOnChange?: (event: EventType) => void) => {
const deafultHandleChange = (e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
const defaultHandleChange = (e: ChangeEvent<HTMLInputElement>) => {
const { value } = e.target;
if (isUnavailable) {
e.preventDefault();
return;
Expand All @@ -48,7 +48,7 @@ const useRadio = (
setValue(value);
};

return propsOnChange ? callHandler(deafultHandleChange, propsOnChange) : deafultHandleChange;
return propsOnChange ? callHandler(defaultHandleChange, propsOnChange) : defaultHandleChange;
};

const handleChange = combineChangeHandler(radioProps.onChange as (event: EventType) => void);
Expand Down
17 changes: 9 additions & 8 deletions packages/radio/src/hooks/useRadioGroup.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import { ForwardedRef, useCallback, useEffect, useRef } from 'react';

const useRadioGroup = (defalutValue: string | null, externalRef?: ForwardedRef<HTMLInputElement>) => {
const useRadioGroup = (defaultValue?: string, externalRef?: ForwardedRef<HTMLInputElement>) => {
const ref = useRef<HTMLDivElement | null>(null);

const setDefaultValueCheck = useCallback(
(el: HTMLInputElement, targetValue: string | null, externalRef?: ForwardedRef<HTMLInputElement>) => {
(el: HTMLInputElement, targetValue?: string, extRef?: ForwardedRef<HTMLInputElement>) => {
const isUnavailable = el.hasAttribute('readonly') || el.hasAttribute('disabled');
if (targetValue && targetValue === el.value && !isUnavailable) {
el.checked = true;
Object.assign(el, { checked: true });
}
if (externalRef && typeof externalRef === 'function') {
externalRef(el);
if (extRef && typeof extRef === 'function') {
extRef(el);
}
return el;
},
[ref]
[]
);

useEffect(() => {
if (ref.current) {
const radioElements = ref.current.querySelectorAll('input[type="radio"]') as NodeListOf<HTMLInputElement>;
radioElements.forEach(el => {
setDefaultValueCheck(el, defalutValue, externalRef);
setDefaultValueCheck(el, defaultValue, externalRef);
});
}
}, [ref]);
}, [defaultValue, externalRef, setDefaultValueCheck]);

return ref;
};
Expand Down
5 changes: 2 additions & 3 deletions packages/radio/src/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,8 @@ export const createRadio = (color: HEX, disabledColor: HEX, disabled: boolean, s
return [radioStyle, disabledStyle(), radioSizeStyle()];
};

export const wrapper = () => {
return css({
export const wrapper = () =>
css({
display: 'inline-block',
position: 'relative'
});
};
2 changes: 1 addition & 1 deletion packages/radio/src/types/base.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export type RadioSize = 'sm' | 'md' | 'lg';
export type RadioValueType = string | number | boolean;
export type RadioValueType = string | number | readonly string[] | undefined | boolean;
2 changes: 1 addition & 1 deletion packages/radio/src/types/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Dispatch, SetStateAction } from 'react';
import type { EventType } from '@jdesignlab/utils';
import type { RadioValueType } from './base';

export type RadioAttributes = { [key: string]: string | ((event: EventType) => void) };
export type RadioAttributes = Record<string, string | ((event: EventType) => void)>;
export interface ReturnContext {
defaultValue?: string;
name: string;
Expand Down
Loading