moderntw_confirms 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -5
- data/README.md +9 -6
- data/lib/generators/moderntw_confirms/install/templates/_moderntw_confirms_modal.html.erb +12 -8
- data/lib/generators/moderntw_confirms/install/templates/moderntw_confirms.rb +10 -6
- data/lib/moderntw_confirms/version.rb +1 -1
- data/lib/moderntw_confirms.rb +26 -10
- data/vendor/assets/javascripts/moderntw_confirms.js +54 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d648dcd53d5b73daa45fcd1762e4fcbbff04f23f4a1bba3ac12dddf8afc307fe
|
|
4
|
+
data.tar.gz: cad308cde28cf3bb0768f10b55e22f4d12ae6f5fa688b624515ddef5950e7df2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dc13da07aa0c8f4730d6e1c84f961fb01cabccce571ed7d283942d9ad563c46fcbfda9f7f31a00fe73a206cdd12033dedfe5d81a4163f1a6844f8930aa8d507b
|
|
7
|
+
data.tar.gz: 9013a015eb6f1a740dc603dba016f4e2431f0d8eaf0678692ae4760eab8108716814578faf1729bbe0bfed1129f1f1e7c0176132c9c05f9ebdd8b0f5a32ae7f4
|
data/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## [1.1.1] - 2025-01-04
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
### Changed
|
|
6
|
+
- **BREAKING (but backwards compatible)**: Refactored configuration to use accessor methods instead of hash keys
|
|
7
|
+
- Old syntax: `config[:backdrop_class] = "..."`
|
|
8
|
+
- New syntax: `config.backdrop_class = "..."`
|
|
9
|
+
- The old hash-based syntax is still supported via the `config` alias for backwards compatibility
|
|
10
|
+
- Removed dependency on ActiveSupport's `mattr_accessor`
|
|
7
11
|
|
|
8
|
-
## [
|
|
12
|
+
## [1.1.0] - 2024-05-xx
|
|
13
|
+
- Default to native confirms on mobile with optional opt-in via config[:enable_on_mobile]
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- Default to native browser confirms on mobile devices with the option to re-enable Tailwind modals via `config[:enable_on_mobile]`
|
|
9
17
|
|
|
10
18
|
## [0.1.0] - 2025-10-21
|
|
11
19
|
|
|
@@ -21,4 +29,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
21
29
|
- Optional Stimulus controller for advanced customization
|
|
22
30
|
- Configurable Tailwind classes via initializer
|
|
23
31
|
- Dynamic content support (works with AJAX/Turbo loaded content)
|
|
24
|
-
- Focus management for accessibility
|
|
32
|
+
- Focus management for accessibility
|
data/README.md
CHANGED
|
@@ -5,6 +5,8 @@ Beautiful Tailwind CSS confirmation modals for Rails applications. Drop-in repla
|
|
|
5
5
|
[](https://badge.fury.io/rb/moderntw_confirms)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
+

|
|
9
|
+
|
|
8
10
|
## Features
|
|
9
11
|
|
|
10
12
|
- **Zero Configuration** - Works with your existing Rails code immediately
|
|
@@ -96,9 +98,14 @@ ModerntwConfirms.configure do |config|
|
|
|
96
98
|
config[:modal_class] = "rounded-3xl shadow-2xl"
|
|
97
99
|
config[:confirm_button_class] = "bg-indigo-600 hover:bg-indigo-700"
|
|
98
100
|
config[:cancel_button_class] = "bg-gray-200 hover:bg-gray-300"
|
|
101
|
+
config[:enable_on_mobile] = true # Opt into modals on phones/tablets
|
|
99
102
|
end
|
|
100
103
|
```
|
|
101
104
|
|
|
105
|
+
### Mobile Behavior
|
|
106
|
+
|
|
107
|
+
Native confirmation dialogs feel familiar on mobile, so the gem defaults to using the browser's built-in confirms for touch devices. If you prefer the Tailwind modal experience everywhere, set `config[:enable_on_mobile] = true` in your initializer.
|
|
108
|
+
|
|
102
109
|
### Animation Customization
|
|
103
110
|
|
|
104
111
|
The animations use CSS transitions and can be modified in the modal partial:
|
|
@@ -133,16 +140,12 @@ The modal includes automatic fallback to native browser confirms for older brows
|
|
|
133
140
|
|
|
134
141
|
## Development
|
|
135
142
|
|
|
136
|
-
After checking out the repo,
|
|
143
|
+
After checking out the repo, run:
|
|
137
144
|
|
|
138
145
|
```bash
|
|
139
|
-
cd test_confirms_app
|
|
140
146
|
bundle install
|
|
141
|
-
rails server
|
|
142
147
|
```
|
|
143
148
|
|
|
144
|
-
Visit http://localhost:3000 to see the examples.
|
|
145
|
-
|
|
146
149
|
### Running Tests
|
|
147
150
|
|
|
148
151
|
```bash
|
|
@@ -170,4 +173,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
170
173
|
|
|
171
174
|
## Acknowledgments
|
|
172
175
|
|
|
173
|
-
Built with Rails and Tailwind CSS. Special thanks to the Rails and Hotwire communities for their excellent frameworks.
|
|
176
|
+
Built with Rails and Tailwind CSS. Special thanks to the Rails and Hotwire communities for their excellent frameworks.
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
<% config = ModerntwConfirms.config %>
|
|
2
|
+
<% enable_on_mobile = config.enable_on_mobile %>
|
|
3
|
+
|
|
1
4
|
<div id="moderntw-confirm-modal"
|
|
2
5
|
class="hidden fixed inset-0 z-[99999] overflow-y-auto"
|
|
3
6
|
aria-labelledby="moderntw-modal-title"
|
|
4
7
|
aria-modal="true"
|
|
5
8
|
role="dialog"
|
|
6
|
-
data-turbo-permanent
|
|
9
|
+
data-turbo-permanent
|
|
10
|
+
data-enable-on-mobile="<%= enable_on_mobile %>">
|
|
7
11
|
|
|
8
12
|
<div class="fixed inset-0" data-modal-backdrop>
|
|
9
13
|
<div class="absolute inset-0 bg-gray-900/40 backdrop-blur-sm"></div>
|
|
@@ -62,7 +66,7 @@
|
|
|
62
66
|
|
|
63
67
|
<style>
|
|
64
68
|
#moderntw-confirm-modal {
|
|
65
|
-
transition: opacity
|
|
69
|
+
transition: opacity 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
66
70
|
will-change: opacity;
|
|
67
71
|
}
|
|
68
72
|
|
|
@@ -75,7 +79,7 @@
|
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
#moderntw-confirm-modal [data-modal-panel] {
|
|
78
|
-
transition:
|
|
82
|
+
transition: transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 180ms ease-out;
|
|
79
83
|
will-change: transform, opacity;
|
|
80
84
|
}
|
|
81
85
|
|
|
@@ -85,20 +89,20 @@
|
|
|
85
89
|
}
|
|
86
90
|
|
|
87
91
|
#moderntw-confirm-modal:not(.modal-showing) [data-modal-panel] {
|
|
88
|
-
transform: scale(0.
|
|
92
|
+
transform: scale(0.95) translateY(10px);
|
|
89
93
|
opacity: 0;
|
|
90
94
|
}
|
|
91
95
|
|
|
92
96
|
@supports (backdrop-filter: blur(0px)) or (-webkit-backdrop-filter: blur(0px)) {
|
|
93
97
|
#moderntw-confirm-modal [data-modal-backdrop] > div {
|
|
94
|
-
-webkit-backdrop-filter: blur(
|
|
95
|
-
backdrop-filter: blur(
|
|
98
|
+
-webkit-backdrop-filter: blur(10px);
|
|
99
|
+
backdrop-filter: blur(10px);
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
@supports not ((backdrop-filter: blur(0px)) or (-webkit-backdrop-filter: blur(0px))) {
|
|
100
104
|
#moderntw-confirm-modal [data-modal-backdrop] > div {
|
|
101
|
-
background-color: rgba(17, 24, 39, 0.
|
|
105
|
+
background-color: rgba(17, 24, 39, 0.72);
|
|
102
106
|
}
|
|
103
107
|
}
|
|
104
|
-
</style>
|
|
108
|
+
</style>
|
|
@@ -3,18 +3,22 @@ ModerntwConfirms.configure do |config|
|
|
|
3
3
|
# These are the default values - modify them to match your design system
|
|
4
4
|
|
|
5
5
|
# Background overlay classes
|
|
6
|
-
config
|
|
6
|
+
config.backdrop_class = "bg-black bg-opacity-50"
|
|
7
7
|
|
|
8
8
|
# Modal container classes
|
|
9
|
-
config
|
|
9
|
+
config.modal_class = "bg-white rounded-lg shadow-xl"
|
|
10
10
|
|
|
11
11
|
# Confirm button classes
|
|
12
|
-
config
|
|
12
|
+
config.confirm_button_class = "bg-blue-500 hover:bg-blue-600 text-white font-semibold py-2 px-4 rounded"
|
|
13
13
|
|
|
14
14
|
# Cancel button classes
|
|
15
|
-
config
|
|
15
|
+
config.cancel_button_class = "bg-gray-300 hover:bg-gray-400 text-gray-800 font-semibold py-2 px-4 rounded"
|
|
16
16
|
|
|
17
17
|
# You can also add custom classes for specific use cases:
|
|
18
18
|
# For delete confirmations, you might want red buttons:
|
|
19
|
-
# config
|
|
20
|
-
|
|
19
|
+
# config.delete_confirm_button_class = "bg-red-500 hover:bg-red-600 text-white font-semibold py-2 px-4 rounded"
|
|
20
|
+
|
|
21
|
+
# Use Tailwind modal confirms on mobile devices (defaults to native mobile confirms)
|
|
22
|
+
# Set to true if you prefer the custom modal experience on phones and tablets
|
|
23
|
+
# config.enable_on_mobile = true
|
|
24
|
+
end
|
data/lib/moderntw_confirms.rb
CHANGED
|
@@ -6,15 +6,31 @@ require_relative "moderntw_confirms/engine" if defined?(Rails)
|
|
|
6
6
|
module ModerntwConfirms
|
|
7
7
|
class Error < StandardError; end
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
class Configuration
|
|
10
|
+
attr_accessor :backdrop_class, :modal_class, :confirm_button_class,
|
|
11
|
+
:cancel_button_class, :enable_on_mobile
|
|
12
|
+
|
|
13
|
+
def initialize
|
|
14
|
+
@backdrop_class = "bg-black bg-opacity-50"
|
|
15
|
+
@modal_class = "bg-white rounded-lg shadow-xl"
|
|
16
|
+
@confirm_button_class = "bg-blue-500 hover:bg-blue-600 text-white font-semibold py-2 px-4 rounded"
|
|
17
|
+
@cancel_button_class = "bg-gray-300 hover:bg-gray-400 text-gray-800 font-semibold py-2 px-4 rounded"
|
|
18
|
+
@enable_on_mobile = false
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class << self
|
|
23
|
+
attr_writer :configuration
|
|
24
|
+
|
|
25
|
+
def configuration
|
|
26
|
+
@configuration ||= Configuration.new
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def configure
|
|
30
|
+
yield configuration
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Alias for backwards compatibility
|
|
34
|
+
alias_method :config, :configuration
|
|
19
35
|
end
|
|
20
36
|
end
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
this.initialized = false;
|
|
10
10
|
this.initializationAttempts = 0;
|
|
11
11
|
this.maxInitAttempts = 3;
|
|
12
|
+
this.useModal = true;
|
|
13
|
+
this.enableOnMobile = false;
|
|
12
14
|
|
|
13
15
|
try {
|
|
14
16
|
this.init();
|
|
@@ -48,6 +50,13 @@
|
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
this.setupModalElements();
|
|
53
|
+
this.readConfiguration();
|
|
54
|
+
this.useModal = this.shouldUseModal();
|
|
55
|
+
|
|
56
|
+
if (!this.useModal) {
|
|
57
|
+
console.info('ModerntwConfirms: Using native browser confirms on mobile devices.');
|
|
58
|
+
}
|
|
59
|
+
|
|
51
60
|
this.interceptTurboConfirms();
|
|
52
61
|
this.setupModalHandlers();
|
|
53
62
|
this.initialized = true;
|
|
@@ -59,6 +68,8 @@
|
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
fallbackToNative() {
|
|
71
|
+
this.useModal = false;
|
|
72
|
+
|
|
62
73
|
if (window.Turbo && window.Turbo.config && window.Turbo.config.forms) {
|
|
63
74
|
Turbo.config.forms.confirm = (message) => {
|
|
64
75
|
return Promise.resolve(window.confirm(message));
|
|
@@ -213,7 +224,7 @@
|
|
|
213
224
|
}
|
|
214
225
|
|
|
215
226
|
showModal(message, callback) {
|
|
216
|
-
if (!this.modal || !this.initialized) {
|
|
227
|
+
if (!this.modal || !this.initialized || !this.useModal) {
|
|
217
228
|
const result = window.confirm(message);
|
|
218
229
|
if (callback) callback(result);
|
|
219
230
|
return;
|
|
@@ -373,6 +384,47 @@
|
|
|
373
384
|
this.modal.removeEventListener('keydown', this.tabHandler);
|
|
374
385
|
}
|
|
375
386
|
}
|
|
387
|
+
|
|
388
|
+
readConfiguration() {
|
|
389
|
+
try {
|
|
390
|
+
if (!this.modal || !this.modal.dataset) {
|
|
391
|
+
this.enableOnMobile = false;
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
this.enableOnMobile = this.modal.dataset.enableOnMobile === 'true';
|
|
396
|
+
} catch (error) {
|
|
397
|
+
console.error('ModerntwConfirms: Error reading configuration', error);
|
|
398
|
+
this.enableOnMobile = false;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
shouldUseModal() {
|
|
403
|
+
try {
|
|
404
|
+
if (this.enableOnMobile) {
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return !this.isMobileDevice();
|
|
409
|
+
} catch (error) {
|
|
410
|
+
console.error('ModerntwConfirms: Error determining modal usage preference', error);
|
|
411
|
+
return true;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
isMobileDevice() {
|
|
416
|
+
try {
|
|
417
|
+
const touchCapable = ('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0);
|
|
418
|
+
const narrowViewport = window.matchMedia ? window.matchMedia('(max-width: 768px)').matches : false;
|
|
419
|
+
const userAgent = navigator.userAgent || navigator.vendor || window.opera || '';
|
|
420
|
+
const mobileRegex = /Mobi|Android|iP(ad|hone|od)|Silk|Kindle|BlackBerry|IEMobile|Opera Mini/i;
|
|
421
|
+
|
|
422
|
+
return touchCapable && (narrowViewport || mobileRegex.test(userAgent));
|
|
423
|
+
} catch (error) {
|
|
424
|
+
console.error('ModerntwConfirms: Error detecting device type', error);
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
376
428
|
}
|
|
377
429
|
|
|
378
430
|
if (typeof window !== 'undefined') {
|
|
@@ -401,4 +453,4 @@
|
|
|
401
453
|
setTimeout(initializeOnce, 100);
|
|
402
454
|
}
|
|
403
455
|
}
|
|
404
|
-
})();
|
|
456
|
+
})();
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moderntw_confirms
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Robin Ciubotaru
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|