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

Add Stimulus Radio Uncheck component #3

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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: 7 additions & 0 deletions components/radio-uncheck/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Changelog

## [1.0.0] - 2024-12-30

### Added

- Adding controller
17 changes: 17 additions & 0 deletions components/radio-uncheck/README.md
Original file line number Diff line number Diff line change
@@ -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.
66 changes: 66 additions & 0 deletions components/radio-uncheck/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<title>Stimulus Radio Uncheck All</title>

<script type="module">
import "../app.css"
import { Application } from "@hotwired/stimulus"
import RadioUncheck from "./src/index"

const application = Application.start()
application.register("radio-uncheck", RadioUncheck)
</script>
</head>

<body>
<div class="relative h-full max-w-5xl mx-auto px-4">
<section class="mt-16">
<form data-controller="radio-uncheck" class="space-y-4">
<div class="flex items-center gap-x-3">
<input
data-radio-uncheck-target="radio"
id="team-1"
name="team"
type="radio"
class="h-4 w-4 border-gray-300 text-orange-600 focus:ring-orange-600"
/>
<label for="team-1" class="block text-sm/6 font-medium text-gray-900">Team 1</label>
</div>
<div class="flex items-center gap-x-3">
<input
data-radio-uncheck-target="radio"
id="team-2"
name="team"
type="radio"
class="h-4 w-4 border-gray-300 text-orange-600 focus:ring-orange-600"
/>
<label for="team-2" class="block text-sm/6 font-medium text-gray-900">Team 2</label>
</div>
<div class="flex items-center gap-x-3">
<input
data-radio-uncheck-target="radio"
id="team-3"
name="team"
type="radio"
class="h-4 w-4 border-gray-300 text-orange-600 focus:ring-orange-600"
/>
<label for="team-3" class="block text-sm/6 font-medium text-gray-900">Team 3</label>
</div>
<div>
<button
type="button"
data-action="radio-uncheck#uncheck"
class="rounded-md bg-orange-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-orange-500"
>
Uncheck
</button>
</div>
</form>
</section>
</div>
</body>
</html>
36 changes: 36 additions & 0 deletions components/radio-uncheck/package.json
Original file line number Diff line number Diff line change
@@ -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": "[email protected]:stimulus-components/stimulus-components.git",
"bugs": {
"url": "https://github.com/stimulus-components/stimulus-components/issues"
},
"author": "Guillaume Briday <[email protected]>",
"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"
}
}
50 changes: 50 additions & 0 deletions components/radio-uncheck/spec/index.test.ts
Original file line number Diff line number Diff line change
@@ -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 = `
<form data-controller="radio-uncheck">
<input data-radio-uncheck-target="radio" id="team-1" name="team" type="radio">
<label for="team-1">Team 1</label>

<input data-radio-uncheck-target="radio" id="team-2" name="team" type="radio">
<label for="team-2">Team 2</label>

<input data-radio-uncheck-target="radio" id="team-3" name="team" type="radio">
<label for="team-3">Team 3</label>

<button type="button" data-action="radio-uncheck#uncheck">Uncheck</button>
</form>
`
})

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)
})
})
})
})
17 changes: 17 additions & 0 deletions components/radio-uncheck/src/index.ts
Original file line number Diff line number Diff line change
@@ -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 }))
})
}
}
4 changes: 4 additions & 0 deletions components/radio-uncheck/tailwind.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.{js,ts}"],
}
3 changes: 3 additions & 0 deletions components/radio-uncheck/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../tsconfig.json"
}
23 changes: 23 additions & 0 deletions components/radio-uncheck/vite.config.mts
Original file line number Diff line number Diff line change
@@ -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",
},
},
},
},
})
49 changes: 49 additions & 0 deletions docs/components/content/Demo/RadioUncheck.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<Block title="Radio Uncheck">
<form data-controller="radio-uncheck" class="space-y-4">
<div class="flex items-center gap-x-3">
<input
id="team-1"
data-radio-uncheck-target="radio"
name="team"
type="radio"
class="size-4 border-gray-300 text-orange-600 focus:ring-orange-600"
/>
<label for="team-1" class="block text-sm/6 font-medium text-gray-900">Team 1</label>
</div>
<div class="flex items-center gap-x-3">
<input
id="team-2"
data-radio-uncheck-target="radio"
name="team"
type="radio"
class="h-4 w-4 border-gray-300 text-orange-600 focus:ring-orange-600"
elalemanyo marked this conversation as resolved.
Show resolved Hide resolved
/>
<label for="team-2" class="block text-sm/6 font-medium text-gray-900">Team 2</label>
</div>
<div class="flex items-center gap-x-3">
<input
id="team-3"
data-radio-uncheck-target="radio"
name="team"
type="radio"
class="h-4 w-4 border-gray-300 text-orange-600 focus:ring-orange-600"
elalemanyo marked this conversation as resolved.
Show resolved Hide resolved
/>
<label for="team-3" class="block text-sm/6 font-medium text-gray-900">Team 3</label>
</div>
<div>
<button
type="button"
data-action="radio-uncheck#uncheck"
class="rounded-md bg-orange-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-orange-500"
>
Uncheck
</button>
</div>
</form>
</Block>
</template>

<script setup>
import Block from "@/components/UI/Block.vue"
</script>
53 changes: 53 additions & 0 deletions docs/content/docs/stimulus-radio-uncheck.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: Radio Uncheck
description: A Stimulus controller to uncheck radio buttons.
elalemanyo marked this conversation as resolved.
Show resolved Hide resolved
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
<div data-controller="radio-uncheck">
<input type="radio" name="radio" value="1" data-radio-uncheck-target="input" />
<label for="radio-1">Radio 1</label>
<input type="radio" name="radio" value="2" data-radio-uncheck-target="input" />
<label for="radio-2">Radio 2</label>
<input type="radio" name="radio" value="3" data-radio-uncheck-target="input" />
<label for="radio-3">Radio 3</label>

<button data-action="radio-uncheck#uncheck">Uncheck</button>
</div>
```

::

## 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.")
}
}
```

::
::
1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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:*",
Expand Down
2 changes: 2 additions & 0 deletions docs/plugins/stimulus.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.