-
-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2ef7e5f
commit 5715bc8
Showing
17 changed files
with
482 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# Changelog | ||
|
||
All notable changes to this project will be documented in this file. | ||
|
||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
## [Unreleased] | ||
|
||
## [1.0.0] - 2024-12-17 | ||
|
||
### Added | ||
|
||
- Adding controller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Stimulus Confirmation | ||
|
||
## Getting started | ||
|
||
A Stimulus controller to confirm actions manually. | ||
|
||
## 📚 Documentation | ||
|
||
See [stimulus-confirmation documentation](https://www.stimulus-components.com/docs/stimulus-confirmation/). | ||
|
||
## 👷♂️ 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
|
||
<title>Stimulus Confirmation</title> | ||
|
||
<script type="module"> | ||
import "../app.css" | ||
import { Application } from "@hotwired/stimulus" | ||
import Confirmation from "./src/index" | ||
|
||
const application = Application.start() | ||
application.register("confirmation", Confirmation) | ||
</script> | ||
</head> | ||
|
||
<body> | ||
<div class="relative h-full max-w-5xl mx-auto px-4"> | ||
<section class="mt-16"> | ||
<form data-controller="confirmation" class="space-y-3"> | ||
<div> | ||
<label for="confirmation" class="block text-sm/6 font-medium text-gray-900">Type "DELETE" to confirm</label> | ||
<div class="mt-2"> | ||
<input | ||
data-confirmation-target="input" | ||
data-confirmation-content="DELETE" | ||
data-action="confirmation#check" | ||
id="confirmation" | ||
class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-orange-600 sm:text-sm/6" | ||
placeholder="Are you sure?" | ||
/> | ||
</div> | ||
</div> | ||
|
||
<div> | ||
<label> | ||
<input data-confirmation-target="input" data-action="confirmation#check" type="checkbox" /> | ||
|
||
I have read the terms and conditions | ||
</label> | ||
</div> | ||
|
||
<div> | ||
<label> | ||
<input data-confirmation-target="input" data-action="confirmation#check" type="checkbox" /> | ||
|
||
I confirm that I want to permanently delete this project | ||
</label> | ||
</div> | ||
|
||
<button | ||
type="submit" | ||
data-confirmation-target="item" | ||
disabled | ||
class="disabled:cursor-not-allowed disabled:bg-red-300 rounded-full bg-red-600 px-3 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600" | ||
> | ||
Delete | ||
</button> | ||
|
||
<input | ||
data-confirmation-target="item" | ||
class="block w-full rounded-md disabled:bg-gray-100 bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-orange-600 sm:text-sm/6" | ||
disabled | ||
value="[email protected]" | ||
/> | ||
</form> | ||
</section> | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"name": "@stimulus-components/confirmation", | ||
"version": "1.0.0", | ||
"description": "A Stimulus controller to confirm actions manually", | ||
"keywords": [ | ||
"stimulus", | ||
"stimulusjs", | ||
"stimulus controller", | ||
"confirmation" | ||
], | ||
"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-confirmation.umd.js", | ||
"module": "dist/stimulus-confirmation.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" | ||
}, | ||
"peerDependencies": { | ||
"@hotwired/stimulus": "^3" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/** | ||
* @jest-environment jsdom | ||
*/ | ||
|
||
import { beforeEach, describe, it, expect } from "vitest" | ||
import { Application } from "@hotwired/stimulus" | ||
import Confirmation from "../src/index" | ||
|
||
const startStimulus = (): void => { | ||
const application = Application.start() | ||
application.register("confirmation", Confirmation) | ||
} | ||
|
||
describe("#check", () => { | ||
describe("with one input", () => { | ||
beforeEach((): void => { | ||
startStimulus() | ||
|
||
document.body.innerHTML = ` | ||
<form data-controller="confirmation"> | ||
<input | ||
id="confirmation" | ||
data-confirmation-target="input" | ||
data-confirmation-content="DELETE" | ||
data-action="confirmation#check" | ||
/> | ||
<button data-confirmation-target="item" disabled>Delete</button> | ||
<input data-confirmation-target="item" disabled /> | ||
</form> | ||
` | ||
}) | ||
|
||
it("should enable all items", (): void => { | ||
const input = document.querySelector<HTMLInputElement>("#confirmation") | ||
const itemsDisabled = document.querySelectorAll<HTMLInputElement>("[data-confirmation-target='item']:disabled") | ||
|
||
expect(itemsDisabled.length).toBe(2) | ||
|
||
input.value = "DELETE" | ||
input.dispatchEvent(new Event("input", { bubbles: true })) | ||
|
||
const itemsEnabled = document.querySelectorAll<HTMLInputElement>("[data-confirmation-target='item']:enabled") | ||
expect(itemsEnabled.length).toBe(2) | ||
}) | ||
|
||
it("should not enable all items", (): void => { | ||
const input = document.querySelector<HTMLInputElement>("#confirmation") | ||
const itemsDisabled = document.querySelectorAll<HTMLInputElement>("[data-confirmation-target='item']:disabled") | ||
|
||
expect(itemsDisabled.length).toBe(2) | ||
|
||
input.value = "FOOBAR" | ||
input.dispatchEvent(new Event("input", { bubbles: true })) | ||
|
||
const itemsEnabled = document.querySelectorAll<HTMLInputElement>("[data-confirmation-target='item']:enabled") | ||
expect(itemsEnabled.length).toBe(0) | ||
}) | ||
}) | ||
|
||
describe("with multiple inputs", () => { | ||
beforeEach((): void => { | ||
startStimulus() | ||
|
||
document.body.innerHTML = ` | ||
<form data-controller="confirmation"> | ||
<input | ||
id="confirmation" | ||
data-confirmation-target="input" | ||
data-confirmation-content="DELETE" | ||
data-action="confirmation#check" | ||
/> | ||
<input type="checkbox" id="checkbox" data-confirmation-target="input"> | ||
<button data-confirmation-target="item" disabled>Delete</button> | ||
<input data-confirmation-target="item" disabled /> | ||
</form> | ||
` | ||
}) | ||
|
||
it("should enable all items", (): void => { | ||
const input = document.querySelector<HTMLInputElement>("#confirmation") | ||
const checkbox = document.querySelector<HTMLInputElement>("#checkbox") | ||
const itemsDisabled = document.querySelectorAll<HTMLInputElement>("[data-confirmation-target='item']:disabled") | ||
|
||
expect(itemsDisabled.length).toBe(2) | ||
|
||
checkbox.click() | ||
|
||
input.value = "DELETE" | ||
input.dispatchEvent(new Event("input", { bubbles: true })) | ||
|
||
const itemsEnabled = document.querySelectorAll<HTMLInputElement>("[data-confirmation-target='item']:enabled") | ||
expect(itemsEnabled.length).toBe(2) | ||
}) | ||
|
||
it("should not enable all items", (): void => { | ||
const input = document.querySelector<HTMLInputElement>("#confirmation") | ||
const itemsDisabled = document.querySelectorAll<HTMLInputElement>("[data-confirmation-target='item']:disabled") | ||
|
||
expect(itemsDisabled.length).toBe(2) | ||
|
||
input.value = "DELETE" | ||
input.dispatchEvent(new Event("input", { bubbles: true })) | ||
|
||
const itemsEnabled = document.querySelectorAll<HTMLInputElement>("[data-confirmation-target='item']:enabled") | ||
expect(itemsEnabled.length).toBe(0) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Controller } from "@hotwired/stimulus" | ||
|
||
export default class Confirmation extends Controller<HTMLFormElement> { | ||
declare inputTargets: HTMLInputElement[] | ||
declare itemTargets: HTMLInputElement[] | HTMLButtonElement[] | ||
|
||
static targets = ["input", "item"] | ||
|
||
check(): void { | ||
const disabled = this.inputTargets.some((input) => { | ||
if (input.type === "checkbox") { | ||
return input.checked === false | ||
} | ||
|
||
return input.dataset.confirmationContent !== input.value | ||
}) | ||
|
||
this.itemTargets.forEach((target) => { | ||
target.disabled = disabled | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}"], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "../../tsconfig.json" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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: "StimulusConfirmation", | ||
fileName: "stimulus-confirmation", | ||
}, | ||
rollupOptions: { | ||
external: ["@hotwired/stimulus"], | ||
output: { | ||
globals: { | ||
"@hotwired/stimulus": "Stimulus", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<template> | ||
<Block title="Confirmation"> | ||
<form data-controller="confirmation" class="space-y-3"> | ||
<div> | ||
<label for="confirmation" class="block text-sm/6 font-medium text-gray-900">Type "DELETE" to confirm</label> | ||
<div class="mt-2"> | ||
<input | ||
id="confirmation" | ||
data-confirmation-target="input" | ||
data-confirmation-content="DELETE" | ||
data-action="confirmation#check" | ||
class="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-orange-600 sm:text-sm/6" | ||
placeholder="Are you sure?" | ||
/> | ||
</div> | ||
</div> | ||
|
||
<button | ||
type="submit" | ||
data-confirmation-target="item" | ||
disabled | ||
class="disabled:cursor-not-allowed disabled:bg-red-300 rounded-full bg-red-600 px-3 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600" | ||
> | ||
Delete | ||
</button> | ||
</form> | ||
</Block> | ||
</template> | ||
|
||
<script setup> | ||
import Block from "@/components/UI/Block.vue" | ||
</script> |
Oops, something went wrong.