diff --git a/components/radio-uncheck/CHANGELOG.md b/components/radio-uncheck/CHANGELOG.md
new file mode 100644
index 0000000..0cc5240
--- /dev/null
+++ b/components/radio-uncheck/CHANGELOG.md
@@ -0,0 +1,7 @@
+# Changelog
+
+## [1.0.0] - 2024-12-30
+
+### Added
+
+- Adding controller
diff --git a/components/radio-uncheck/README.md b/components/radio-uncheck/README.md
new file mode 100644
index 0000000..eb52cc2
--- /dev/null
+++ b/components/radio-uncheck/README.md
@@ -0,0 +1,17 @@
+# Stimulus Radio Uncheck
+
+## Getting started
+
+A Stimulus controller for unchecking all radio buttons in a group.
+
+## 📚 Documentation
+
+See [stimulus-radio-uncheck documentation](https://www.stimulus-components.com/docs/stimulus-radio-uncheck/).
+
+## 👷♂️ Contributing
+
+Do not hesitate to contribute to the project by adapting or adding features ! Bug reports or pull requests are welcome.
+
+## 📝 License
+
+This project is released under the [MIT](http://opensource.org/licenses/MIT) license.
diff --git a/components/radio-uncheck/index.html b/components/radio-uncheck/index.html
new file mode 100644
index 0000000..d34e5de
--- /dev/null
+++ b/components/radio-uncheck/index.html
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+ Stimulus Radio Uncheck All
+
+
+
+
+
+
+
+
diff --git a/components/radio-uncheck/package.json b/components/radio-uncheck/package.json
new file mode 100644
index 0000000..e7593f5
--- /dev/null
+++ b/components/radio-uncheck/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "@stimulus-components/radio-uncheck",
+ "version": "1.0.0",
+ "description": "A Stimulus controller to uncheck all radio buttons in a group.",
+ "keywords": [
+ "stimulus",
+ "stimulusjs",
+ "stimulus controller",
+ "radio",
+ "radio-uncheck"
+ ],
+ "repository": "git@github.com:stimulus-components/stimulus-components.git",
+ "bugs": {
+ "url": "https://github.com/stimulus-components/stimulus-components/issues"
+ },
+ "author": "Guillaume Briday ",
+ "license": "MIT",
+ "homepage": "https://github.com/stimulus-components/stimulus-components",
+ "private": false,
+ "publishConfig": {
+ "access": "public"
+ },
+ "main": "dist/stimulus-radio-uncheck.umd.js",
+ "module": "dist/stimulus-radio-uncheck.mjs",
+ "types": "dist/types/index.d.ts",
+ "scripts": {
+ "types": "tsc --noEmit false --declaration true --emitDeclarationOnly true --outDir dist/types",
+ "dev": "vite",
+ "build": "vite build && pnpm run types",
+ "version": "pnpm run build",
+ "np": "np --no-2fa"
+ },
+ "peerDependencies": {
+ "@hotwired/stimulus": "^3"
+ }
+}
diff --git a/components/radio-uncheck/spec/index.test.ts b/components/radio-uncheck/spec/index.test.ts
new file mode 100644
index 0000000..9345dfc
--- /dev/null
+++ b/components/radio-uncheck/spec/index.test.ts
@@ -0,0 +1,50 @@
+/**
+ * @jest-environment jsdom
+ */
+
+import { beforeEach, describe, it, expect } from "vitest"
+import { Application } from "@hotwired/stimulus"
+import RadioUncheck from "../src/index"
+
+const startStimulus = (): void => {
+ const application = Application.start()
+ application.register("radio-uncheck", RadioUncheck)
+}
+
+beforeEach((): void => {
+ startStimulus()
+
+ document.body.innerHTML = `
+
+ `
+})
+
+describe("#uncheck", () => {
+ it("should uncheck all radio buttons", (): void => {
+ const uncheckButton: HTMLButtonElement = document.querySelector("[data-action='radio-uncheck#uncheck']")
+ const radios: HTMLInputElement[] = [
+ document.querySelector("#team-1"),
+ document.querySelector("#team-2"),
+ document.querySelector("#team-3"),
+ ]
+
+ radios.forEach((radioToCheck) => {
+ radioToCheck.checked = true
+ uncheckButton.click()
+ radios.forEach((radio) => {
+ expect(radio.checked).toBe(false)
+ })
+ })
+ })
+})
diff --git a/components/radio-uncheck/src/index.ts b/components/radio-uncheck/src/index.ts
new file mode 100644
index 0000000..8ff9c67
--- /dev/null
+++ b/components/radio-uncheck/src/index.ts
@@ -0,0 +1,17 @@
+import { Controller } from "@hotwired/stimulus"
+
+export default class RadioUncheckApp extends Controller {
+ declare hasRadioTarget: boolean
+ declare radioTargets: HTMLInputElement[]
+
+ static targets = ["radio"]
+
+ uncheck(): void {
+ if (!this.hasRadioTarget) return
+
+ this.radioTargets.forEach((radio) => {
+ radio.checked = false
+ radio.dispatchEvent(new Event("change", { bubbles: true }))
+ })
+ }
+}
diff --git a/components/radio-uncheck/tailwind.config.ts b/components/radio-uncheck/tailwind.config.ts
new file mode 100644
index 0000000..0155e63
--- /dev/null
+++ b/components/radio-uncheck/tailwind.config.ts
@@ -0,0 +1,4 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+ content: ["./index.html", "./src/**/*.{js,ts}"],
+}
diff --git a/components/radio-uncheck/tsconfig.json b/components/radio-uncheck/tsconfig.json
new file mode 100644
index 0000000..4082f16
--- /dev/null
+++ b/components/radio-uncheck/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "../../tsconfig.json"
+}
diff --git a/components/radio-uncheck/vite.config.mts b/components/radio-uncheck/vite.config.mts
new file mode 100644
index 0000000..5cf45cd
--- /dev/null
+++ b/components/radio-uncheck/vite.config.mts
@@ -0,0 +1,23 @@
+import { resolve } from "path"
+import { defineConfig } from "vite"
+
+export default defineConfig({
+ esbuild: {
+ minifyIdentifiers: false,
+ },
+ build: {
+ lib: {
+ entry: resolve(__dirname, "src/index.ts"),
+ name: "StimulusRadioUncheck",
+ fileName: "stimulus-radio-uncheck",
+ },
+ rollupOptions: {
+ external: ["@hotwired/stimulus"],
+ output: {
+ globals: {
+ "@hotwired/stimulus": "Stimulus",
+ },
+ },
+ },
+ },
+})
diff --git a/docs/components/content/Demo/RadioUncheck.vue b/docs/components/content/Demo/RadioUncheck.vue
new file mode 100644
index 0000000..9094829
--- /dev/null
+++ b/docs/components/content/Demo/RadioUncheck.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
diff --git a/docs/content/docs/stimulus-radio-uncheck.md b/docs/content/docs/stimulus-radio-uncheck.md
new file mode 100644
index 0000000..68a8005
--- /dev/null
+++ b/docs/content/docs/stimulus-radio-uncheck.md
@@ -0,0 +1,53 @@
+---
+title: Radio Uncheck
+description: A Stimulus controller for unchecking all radio buttons in a group.
+package: radio-uncheck
+packagePath: "@stimulus-components/radio-uncheck"
+isNew: true
+---
+
+## Installation
+
+:installation-block{:package="package" :packagePath="packagePath" controllerName="radio-uncheck"}
+
+## Examples
+
+:radio-uncheck
+
+## Usage
+
+::code-block{tabName="app/views/index.html"}
+
+```html
+
+
+
+
+
+
+
+
+
+
+```
+
+::
+
+## Extending Controller
+
+::extending-controller
+::code-block{tabName="app/javascript/controllers/radio_uncheck_controller.js"}
+
+```js
+import RadioUncheck from "@stimulus-components/radio-uncheck"
+
+export default class extends RadioUncheckController {
+ connect() {
+ super.connect()
+ console.log("Do what you want here.")
+ }
+}
+```
+
+::
+::
diff --git a/docs/package.json b/docs/package.json
index 0b18ebd..8a1b94e 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -35,6 +35,7 @@
"@stimulus-components/password-visibility": "workspace:*",
"@stimulus-components/popover": "workspace:*",
"@stimulus-components/rails-nested-form": "workspace:*",
+ "@stimulus-components/radio-uncheck": "workspace:*",
"@stimulus-components/read-more": "workspace:*",
"@stimulus-components/remote-rails": "workspace:*",
"@stimulus-components/reveal": "workspace:*",
diff --git a/docs/plugins/stimulus.client.ts b/docs/plugins/stimulus.client.ts
index ff040c1..d713c95 100644
--- a/docs/plugins/stimulus.client.ts
+++ b/docs/plugins/stimulus.client.ts
@@ -16,6 +16,7 @@ import Lightbox from "@stimulus-components/lightbox/src"
import Notification from "@stimulus-components/notification/src"
import PasswordVisibility from "@stimulus-components/password-visibility/src"
import Popover from "@stimulus-components/popover/src"
+import RadioUncheck from "@stimulus-components/radio-uncheck/src"
import RailsNestedForm from "@stimulus-components/rails-nested-form/src"
import ReadMore from "@stimulus-components/read-more/src"
import RemoteRails from "@stimulus-components/remote-rails/src"
@@ -47,6 +48,7 @@ export default defineNuxtPlugin(() => {
application.register("notification", Notification)
application.register("password-visibility", PasswordVisibility)
application.register("popover", Popover)
+ application.register("radio-uncheck", RadioUncheck)
application.register("read-more", ReadMore)
application.register("remote", RemoteRails)
application.register("reveal", Reveal)
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c98132c..cf3b1f0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -192,6 +192,12 @@ importers:
specifier: ^3
version: 3.2.2
+ components/radio-uncheck:
+ dependencies:
+ '@hotwired/stimulus':
+ specifier: ^3
+ version: 3.2.2
+
components/rails-nested-form:
dependencies:
'@hotwired/stimulus':