Skip to content
Merged
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"@radix-ui/react-dialog": "^1.1.10",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-progress": "^1.1.7",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-slot": "^1.2.2",
"@radix-ui/react-switch": "^1.2.4",
"@radix-ui/react-toggle": "^1.1.9",
Expand Down
53 changes: 53 additions & 0 deletions src/shared/ui/radio/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
'use client';

import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
import { cva } from 'class-variance-authority';
import * as React from 'react';
import { cn } from '@/shared/shadcn/lib/utils';

function RadioGroup({
className,
...props
}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {
return (
<RadioGroupPrimitive.Root
data-slot="radio-group"
className={className}
{...props}
/>
);
}

const radioGroupItemVariants = cva(
'border-border-default hover:bg-fill-neutral-subtle-hover disabled:border-border-disabled disabled:bg-icon-disabled data-[state=checked]:border-border-success rounded-full border-2 bg-white data-[state=checked]:border-4',
{
variants: {
size: {
medium: 'h-[16px] w-[16px]',
large: 'h-[20px] w-[20px]',
},
},
defaultVariants: {
size: 'large',
},
},
);

function RadioGroupItem({
size = 'large',
className,
...props
}: { size?: 'medium' | 'large' } & React.ComponentProps<
typeof RadioGroupPrimitive.RadioGroupItem
>) {
return (
<RadioGroupPrimitive.RadioGroupItem
className={cn(radioGroupItemVariants({ size }), className)}
{...props}
>
<RadioGroupPrimitive.RadioGroupIndicator className="flex h-full w-full items-center justify-center rounded-full" />
</RadioGroupPrimitive.RadioGroupItem>
);
}

export { RadioGroup, RadioGroupItem };
49 changes: 49 additions & 0 deletions src/stories/ui/radio.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Meta, StoryObj } from '@storybook/react';
import { useState } from 'react';
import Button from '@/shared/ui/button';
import { RadioGroup, RadioGroupItem } from '@/shared/ui/radio';

const meta: Meta<typeof RadioGroup> = {
component: RadioGroup,
parameters: {
docs: {
description: {
story: 'RadioGroupItem 컴포넌트의 id와 label의 htmlFor을 맞춰주세요.',
},
},
},
tags: ['autodocs'],
};

export default meta;
type Story = StoryObj<typeof RadioGroup>;

export const Default: Story = {
render: () => {
const [state, setState] = useState<'first' | 'second'>('first');

return (
<div>
<RadioGroup
className="flex flex-col gap-2.5"
defaultValue="first"
onValueChange={(value: 'first' | 'second') => setState(value)}
>
<div className="flex items-center gap-100">
<RadioGroupItem value="first" id="option1" />
<label htmlFor="option1">first</label>
</div>
<div className="flex items-center gap-100">
<RadioGroupItem value="second" id="option2" />

<label htmlFor="option2">second</label>
</div>
</RadioGroup>

<Button type="button" onClick={() => console.log(state)}>
submit
</Button>
</div>
);
},
};
56 changes: 56 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3024,6 +3024,34 @@ __metadata:
languageName: node
linkType: hard

"@radix-ui/react-radio-group@npm:^1.3.8":
version: 1.3.8
resolution: "@radix-ui/react-radio-group@npm:1.3.8"
dependencies:
"@radix-ui/primitive": "npm:1.1.3"
"@radix-ui/react-compose-refs": "npm:1.1.2"
"@radix-ui/react-context": "npm:1.1.2"
"@radix-ui/react-direction": "npm:1.1.1"
"@radix-ui/react-presence": "npm:1.1.5"
"@radix-ui/react-primitive": "npm:2.1.3"
"@radix-ui/react-roving-focus": "npm:1.1.11"
"@radix-ui/react-use-controllable-state": "npm:1.2.2"
"@radix-ui/react-use-previous": "npm:1.1.1"
"@radix-ui/react-use-size": "npm:1.1.1"
peerDependencies:
"@types/react": "*"
"@types/react-dom": "*"
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 10c0/23af8e8b833da1fc4aa4e67c3607dedee4fc5b39278d2e2b820bec7f7b3c0891b006a8a35c57ba436ddf18735bbd8dad9a598d14632a328753a875fde447975c
languageName: node
linkType: hard

"@radix-ui/react-roving-focus@npm:1.1.10":
version: 1.1.10
resolution: "@radix-ui/react-roving-focus@npm:1.1.10"
Expand Down Expand Up @@ -3051,6 +3079,33 @@ __metadata:
languageName: node
linkType: hard

"@radix-ui/react-roving-focus@npm:1.1.11":
version: 1.1.11
resolution: "@radix-ui/react-roving-focus@npm:1.1.11"
dependencies:
"@radix-ui/primitive": "npm:1.1.3"
"@radix-ui/react-collection": "npm:1.1.7"
"@radix-ui/react-compose-refs": "npm:1.1.2"
"@radix-ui/react-context": "npm:1.1.2"
"@radix-ui/react-direction": "npm:1.1.1"
"@radix-ui/react-id": "npm:1.1.1"
"@radix-ui/react-primitive": "npm:2.1.3"
"@radix-ui/react-use-callback-ref": "npm:1.1.1"
"@radix-ui/react-use-controllable-state": "npm:1.2.2"
peerDependencies:
"@types/react": "*"
"@types/react-dom": "*"
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
peerDependenciesMeta:
"@types/react":
optional: true
"@types/react-dom":
optional: true
checksum: 10c0/2cd43339c36e89a3bf1db8aab34b939113dfbde56bf3a33df2d74757c78c9489b847b1962f1e2441c67e41817d120cb6177943e0f655f47bc1ff8e44fd55b1a2
languageName: node
linkType: hard

"@radix-ui/react-slot@npm:1.2.0":
version: 1.2.0
resolution: "@radix-ui/react-slot@npm:1.2.0"
Expand Down Expand Up @@ -10753,6 +10808,7 @@ __metadata:
"@radix-ui/react-dialog": "npm:^1.1.10"
"@radix-ui/react-dropdown-menu": "npm:^2.1.15"
"@radix-ui/react-progress": "npm:^1.1.7"
"@radix-ui/react-radio-group": "npm:^1.3.8"
"@radix-ui/react-slot": "npm:^1.2.2"
"@radix-ui/react-switch": "npm:^1.2.4"
"@radix-ui/react-toggle": "npm:^1.1.9"
Expand Down