diff --git a/app/(sink)/demo/components/page.tsx b/app/(sink)/demo/components/page.tsx
index d551b44..bdf95b4 100644
--- a/app/(sink)/demo/components/page.tsx
+++ b/app/(sink)/demo/components/page.tsx
@@ -15,6 +15,7 @@ import {
TabsTriggerList,
} from "@/packages/ui";
import { Card } from "@/packages/ui/Cards/Card";
+import { RadioGroup } from "@/packages/ui/Form/Radio";
import BadgeStyleVariants from "@/preview/components/badge-style-variants";
import TestimonialCard from "@/preview/components/card-style-testimonial";
import { CheckCircle } from "lucide-react";
@@ -41,6 +42,14 @@ export default function page() {
+
+
+ Option 1
+ Option 2
+ Option 3
+
+
+
diff --git a/config/components.ts b/config/components.ts
index 2070210..60bc3d6 100644
--- a/config/components.ts
+++ b/config/components.ts
@@ -1,6 +1,21 @@
import { lazy } from "react";
-export const componentConfig = {
+export const componentConfig: {
+ core: {
+ [key: string]: {
+ name: string;
+ filePath: string;
+ preview?: React.LazyExoticComponent<() => JSX.Element>;
+ };
+ };
+ examples: {
+ [key: string]: {
+ name: string;
+ filePath: string;
+ preview: React.LazyExoticComponent<() => JSX.Element>;
+ };
+ };
+} = {
core: {
accordion: {
name: "accordion",
@@ -38,6 +53,10 @@ export const componentConfig = {
name: "menu",
filePath: "packages/ui/Menu/Menu.tsx",
},
+ radio: {
+ name: "radio",
+ filePath: "packages/ui/Form/Radio.tsx",
+ },
text: {
name: "text",
filePath: "packages/ui/Text/Text.tsx",
@@ -163,9 +182,11 @@ export const componentConfig = {
filePath: "preview/components/checkbox-style-sizes.tsx",
preview: lazy(() => import("@/preview/components/checkbox-style-sizes")),
},
- "dropdown-style-default": {
- name: "dropdown-style-default",
- },
+ // "dropdown-style-default": {
+ // name: "dropdown-style-default",
+ // filePath: "preview/components/dropdown-style-default.tsx",
+ // preview: lazy(() => import("@/preview/components/dropdown-style-default")),
+ // },
"input-style-default": {
name: "input-style-default",
filePath: "preview/components/input-style-default.tsx",
@@ -176,6 +197,21 @@ export const componentConfig = {
filePath: "preview/components/menu-style-default.tsx",
preview: lazy(() => import("@/preview/components/menu-style-default")),
},
+ "radio-style-default": {
+ name: "radio-style-default",
+ filePath: "preview/components/radio-style-default.tsx",
+ preview: lazy(() => import("@/preview/components/radio-style-default")),
+ },
+ "radio-style-variants": {
+ name: "radio-style-variants",
+ filePath: "preview/components/radio-style-variants.tsx",
+ preview: lazy(() => import("@/preview/components/radio-style-variants")),
+ },
+ "radio-style-sizes": {
+ name: "radio-style-sizes",
+ filePath: "preview/components/radio-style-sizes.tsx",
+ preview: lazy(() => import("@/preview/components/radio-style-sizes")),
+ },
"textarea-style-default": {
name: "textarea-style-default",
filePath: "preview/components/textarea-style-default.tsx",
diff --git a/config/navigation.ts b/config/navigation.ts
index f67cb04..815c3df 100644
--- a/config/navigation.ts
+++ b/config/navigation.ts
@@ -27,6 +27,7 @@ export const navConfig: INavigationConfig = {
{ title: "Dialog", href: `${componentsRoute}/dialog` },
{ title: "Input", href: `${componentsRoute}/input` },
{ title: "Menu", href: `${componentsRoute}/menu` },
+ { title: "Radio", href: `${componentsRoute}/radio`, tag: "New" },
{ title: "Tab", href: `${componentsRoute}/tab` },
{ title: "Textarea", href: `${componentsRoute}/textarea` },
{ title: "Text", href: `${componentsRoute}/text` },
diff --git a/content/docs/components/radio.mdx b/content/docs/components/radio.mdx
new file mode 100644
index 0000000..3b6fb15
--- /dev/null
+++ b/content/docs/components/radio.mdx
@@ -0,0 +1,42 @@
+---
+title: Radio
+description: Sometimes you need to pick multiple options! That's where the Radio component comes into play.
+lastUpdated: 20 Feb, 2024
+links:
+ api_reference: https://www.radix-ui.com/primitives/docs/components/radio-group#api-reference
+ source: https://github.com/Logging-Stuff/RetroUI/blob/main/packages/ui/Form/Radio.tsx
+---
+
+
+
+
+
+## Installation
+
+#### 1. Install dependencies:
+
+```sh
+npm install @radix-ui/react-radio-group class-variance-authority
+```
+
+
+
+#### 2. Copy the code 👇 into your project:
+
+
+
+
+
+## Examples
+
+### Variants
+
+
+
+
+
+### Sizes
+
+
+
+
diff --git a/package.json b/package.json
index c9c8b3d..b58e48d 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"@radix-ui/react-checkbox": "^1.1.4",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-dropdown-menu": "^2.1.2",
+ "@radix-ui/react-radio-group": "^1.2.3",
"@radix-ui/react-visually-hidden": "^1.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
diff --git a/packages/ui/Form/Checkbox.tsx b/packages/ui/Form/Checkbox.tsx
index 960e490..e471d92 100644
--- a/packages/ui/Form/Checkbox.tsx
+++ b/packages/ui/Form/Checkbox.tsx
@@ -6,7 +6,7 @@ import { Check } from "lucide-react";
const checkboxVariants = cva("border-black border-2", {
variants: {
variant: {
- default: " data-[state=checked]:bg-primary-400",
+ default: " data-[state=checked]:bg-primary-500",
outline: "",
solid: "data-[state=checked]:bg-black *:text-white",
},
diff --git a/packages/ui/Form/Radio.tsx b/packages/ui/Form/Radio.tsx
new file mode 100644
index 0000000..59c643d
--- /dev/null
+++ b/packages/ui/Form/Radio.tsx
@@ -0,0 +1,82 @@
+import { cn } from "@/lib/utils";
+import * as RadioPrimitive from "@radix-ui/react-radio-group";
+import { cva, VariantProps } from "class-variance-authority";
+
+const radioVariants = cva("border-black border-2", {
+ variants: {
+ variant: {
+ default: "",
+ outline: "",
+ solid: "",
+ },
+ size: {
+ sm: "h-4 w-4",
+ md: "h-5 w-5",
+ lg: "h-6 w-6",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "md",
+ },
+});
+
+const radioIndicatorVariants = cva("flex ", {
+ variants: {
+ variant: {
+ default: "bg-primary-500 border-2 border-black",
+ outline: "border-2 border-black",
+ solid: "bg-black",
+ },
+ size: {
+ sm: "h-2 w-2",
+ md: "h-2.5 w-2.5",
+ lg: "h-3.5 w-3.5",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "md",
+ },
+});
+
+interface RadioGroupProps
+ extends React.ComponentProps {}
+
+export const RadioGroupRoot = ({ className, ...props }: RadioGroupProps) => (
+
+);
+
+interface RadioProps
+ extends React.ComponentProps,
+ VariantProps {}
+
+export const RadioItem = ({
+ children,
+ className,
+ size,
+ variant,
+ ...props
+}: RadioProps) => (
+
+
+
+
+ {children}
+
+);
+
+const RadioComponent = Object.assign(RadioGroupRoot, {
+ Item: RadioItem,
+});
+
+export { RadioComponent as RadioGroup };
diff --git a/packages/ui/Form/index.tsx b/packages/ui/Form/index.tsx
index 980578a..9c7c8f7 100644
--- a/packages/ui/Form/index.tsx
+++ b/packages/ui/Form/index.tsx
@@ -1,3 +1,4 @@
export * from "./Input";
export * from "./Textarea";
export * from "./Checkbox";
+export * from "./Radio";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index af34681..f18216d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -26,6 +26,9 @@ importers:
'@radix-ui/react-dropdown-menu':
specifier: ^2.1.2
version: 2.1.2(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
+ '@radix-ui/react-radio-group':
+ specifier: ^1.2.3
+ version: 1.2.3(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
'@radix-ui/react-visually-hidden':
specifier: ^1.1.0
version: 1.1.0(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
@@ -725,6 +728,19 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-collection@1.1.2':
+ resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==}
+ 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
+
'@radix-ui/react-compose-refs@1.1.0':
resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==}
peerDependencies:
@@ -931,6 +947,19 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-radio-group@1.2.3':
+ resolution: {integrity: sha512-xtCsqt8Rp09FK50ItqEqTJ7Sxanz8EM8dnkVIhJrc/wkMMomSmXHvYbhv3E7Zx4oXh98aaLt9W679SUYXg4IDA==}
+ 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
+
'@radix-ui/react-roving-focus@1.1.0':
resolution: {integrity: sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==}
peerDependencies:
@@ -944,6 +973,19 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-roving-focus@1.1.2':
+ resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==}
+ 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
+
'@radix-ui/react-slot@1.1.0':
resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==}
peerDependencies:
@@ -3895,6 +3937,18 @@ snapshots:
'@types/react': 18.0.0
'@types/react-dom': 18.0.0
+ '@radix-ui/react-collection@1.1.2(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
+ '@radix-ui/react-slot': 1.1.2(@types/react@18.0.0)(react@18.0.0)
+ react: 18.0.0
+ react-dom: 18.0.0(react@18.0.0)
+ optionalDependencies:
+ '@types/react': 18.0.0
+ '@types/react-dom': 18.0.0
+
'@radix-ui/react-compose-refs@1.1.0(@types/react@18.0.0)(react@18.0.0)':
dependencies:
react: 18.0.0
@@ -4091,6 +4145,24 @@ snapshots:
'@types/react': 18.0.0
'@types/react-dom': 18.0.0
+ '@radix-ui/react-radio-group@1.2.3(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-direction': 1.1.0(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
+ '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-use-previous': 1.1.0(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-use-size': 1.1.0(@types/react@18.0.0)(react@18.0.0)
+ react: 18.0.0
+ react-dom: 18.0.0(react@18.0.0)
+ optionalDependencies:
+ '@types/react': 18.0.0
+ '@types/react-dom': 18.0.0
+
'@radix-ui/react-roving-focus@1.1.0(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)':
dependencies:
'@radix-ui/primitive': 1.1.0
@@ -4108,6 +4180,23 @@ snapshots:
'@types/react': 18.0.0
'@types/react-dom': 18.0.0
+ '@radix-ui/react-roving-focus@1.1.2(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-direction': 1.1.0(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-id': 1.1.0(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.0.0)(@types/react@18.0.0)(react-dom@18.0.0(react@18.0.0))(react@18.0.0)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.0.0)(react@18.0.0)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.0.0)(react@18.0.0)
+ react: 18.0.0
+ react-dom: 18.0.0(react@18.0.0)
+ optionalDependencies:
+ '@types/react': 18.0.0
+ '@types/react-dom': 18.0.0
+
'@radix-ui/react-slot@1.1.0(@types/react@18.0.0)(react@18.0.0)':
dependencies:
'@radix-ui/react-compose-refs': 1.1.0(@types/react@18.0.0)(react@18.0.0)
diff --git a/preview/components/radio-style-default.tsx b/preview/components/radio-style-default.tsx
new file mode 100644
index 0000000..543dc17
--- /dev/null
+++ b/preview/components/radio-style-default.tsx
@@ -0,0 +1,20 @@
+import { RadioGroup } from "@/packages/ui";
+
+export default function RadioStyleSizes() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/preview/components/radio-style-sizes.tsx b/preview/components/radio-style-sizes.tsx
new file mode 100644
index 0000000..3dbf494
--- /dev/null
+++ b/preview/components/radio-style-sizes.tsx
@@ -0,0 +1,26 @@
+import { RadioGroup } from "@/packages/ui";
+
+export default function RadioStyleSizes() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/preview/components/radio-style-variants.tsx b/preview/components/radio-style-variants.tsx
new file mode 100644
index 0000000..9609337
--- /dev/null
+++ b/preview/components/radio-style-variants.tsx
@@ -0,0 +1,22 @@
+import { RadioGroup } from "@/packages/ui";
+
+export default function RadioStyleVariants() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}