diff --git a/src/components/common/input/RadioInput.tsx b/src/components/common/input/RadioInput.tsx new file mode 100644 index 0000000..e11cae1 --- /dev/null +++ b/src/components/common/input/RadioInput.tsx @@ -0,0 +1,48 @@ +import clsx from 'clsx' + +import { handleKeyDown } from '@/utils/handleKeyDown' + +interface RadioInputProps extends React.InputHTMLAttributes { + label: string +} + +export const RadioInput = ({ + label, + className = '', + checked, + disabled, + onChange, + ...props +}: RadioInputProps): JSX.Element => { + const labelClass = clsx( + 'flex cursor-pointer items-center', + disabled && 'cursor-not-allowed opacity-50', + className + ) + + return ( + + ) +} diff --git a/src/stories/common/input/RadioInput.stories.ts b/src/stories/common/input/RadioInput.stories.ts new file mode 100644 index 0000000..a77e956 --- /dev/null +++ b/src/stories/common/input/RadioInput.stories.ts @@ -0,0 +1,21 @@ +import { fn } from '@storybook/test' + +import { RadioInput } from '@/components/common/input/RadioInput' + +export default { + title: 'Common/Input/RadioInput', + component: RadioInput, + parameters: { + layout: 'centered', + }, + tags: ['common', 'radio'], + args: { + onChange: fn(), + }, +} + +export const Default = { + args: { + label: '회사 ‧ 학교', + }, +} diff --git a/src/styles/globals.css b/src/styles/globals.css index 454fdbd..9b65896 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -14,3 +14,25 @@ select { outline: 0; cursor: pointer; } + +input[type='radio'] { + display: none; +} +.custom-radio { + @apply relative inline-block h-20 w-20 cursor-pointer rounded-full border-[1.4px] border-solid border-gray-300; +} +.custom-radio::before { + content: ''; + @apply absolute left-1/2 top-1/2 block h-12 w-12 -translate-x-1/2 -translate-y-1/2 rounded-full; +} +input[type='radio']:checked + .custom-radio { + @apply border-primary-normal; +} + +input[type='radio']:checked + .custom-radio::before { + @apply bg-primary-normal; +} + +label:focus-within .custom-radio { + @apply ring-1 ring-primary-normal; +} \ No newline at end of file diff --git a/src/utils/handleKeyDown.ts b/src/utils/handleKeyDown.ts new file mode 100644 index 0000000..ca25da9 --- /dev/null +++ b/src/utils/handleKeyDown.ts @@ -0,0 +1,9 @@ +export const handleKeyDown = ( + e: React.KeyboardEvent, + callback: () => void, + disabled?: boolean +): void => { + if (e.key === 'Enter' && !disabled) { + callback() + } +}