Skip to content

Commit 0e5a07b

Browse files
committed
feat(popup): add close-esc-key parameter to control ESC key behavior
- Add new close-esc-key parameter with boolean control - Implement JavaScript ESC key prevention logic - Enhance README with comprehensive opening/closing examples - Restructure documentation for better usability - Add acknowledgment of Micromodal.js dependency - Bump version to 1.1.0
1 parent 75a538a commit 0e5a07b

File tree

4 files changed

+206
-17
lines changed

4 files changed

+206
-17
lines changed

README.md

Lines changed: 170 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ WordPress plugin that provides shortcode for creating popups.
1010

1111
Kntnt Popup is a lightweight, customizable WordPress plugin that provides an easy-to-use shortcode for creating modal popups on your website. With this plugin, you can create popups triggered by various user actions without writing any JavaScript or HTML code.
1212

13+
This plugin is built on top of [Micromodal.js](https://micromodal.vercel.app/) by Indrashish Ghosh, a powerful and accessible micro modal library. We extend our sincere gratitude to the Micromodal.js project and its contributors for providing such an excellent foundation for creating accessible modal dialogs.
14+
1315
### Key Features:
1416

1517
- Simple shortcode implementation with extensive customization options
@@ -36,31 +38,161 @@ The plugin provides a shortcode `[popup]...[/popup]` where the content between t
3638
Basic usage:
3739

3840
```
39-
[popup show-after-time="5"]Your popup content here. Can include text, images, forms, and even other shortcodes.[/popup]
41+
[popup modal show-after-time=3 close-button close-outside-click close-esc-key]This is a typical pop-up.[/popup]
42+
```
43+
44+
Here's a sophisticated popup that combines multiple opening triggers and closing methods:
45+
46+
```
47+
[popup modal show-after-time=30 show-after-scroll=50 show-on-exit-intent close-button close-outside-click close-esc-key overlay-color="rgba(0 0 0 / 50%)" style-overlay="backdrop-filter:blur(5px);" open-animation="fade-in-top" close-animation="fade-out-top" aria-label-popup="Demo"]
48+
<h2>Popup demo</h2>
49+
<p>This popup can be triggered by:</p>
50+
<ul>
51+
<li>Waiting 30 seconds on the page</li>
52+
<li>Scrolling 50% of the page</li>
53+
<li>Moving your mouse to leave the page</li>
54+
</ul>
55+
<p>You can close it by:</p>
56+
<ul>
57+
<li>Clicking the × button</li>
58+
<li>Clicking outside the popup</li>
59+
<li>Pressing the ESC key</li>
60+
<li>Or by <a data-popup-close>clicking this link</a></li>
61+
</ul>
62+
[/popup]
63+
```
64+
65+
This example creates a modal popup that will appear when ANY of the three trigger conditions are met (whichever happens first). Users can then close it using any of the four available methods, providing maximum flexibility and user control.
66+
67+
## Triggers
68+
69+
Kntnt Popup offers multiple ways to control when and how popups appear and disappear. You can use automatic triggers, manual controls, or combine multiple methods to create the perfect user experience.
70+
71+
### Time-based trigger
72+
73+
**Delayed display:** Show a popup after a specified number of seconds:
74+
```
75+
[popup show-after-time="10"]This popup appears after 10 seconds.[/popup]
76+
```
77+
78+
**Immediate display:** Show a popup as soon as the page loads:
79+
```
80+
[popup show-after-time="0"]This popup appears immediately when the page loads.[/popup]
81+
```
82+
83+
### Scroll-based trigger
84+
85+
Show a popup when the user has scrolled a certain percentage of the page:
86+
```
87+
[popup show-after-scroll="75"]This popup appears when you've scrolled 75% of the page.[/popup]
4088
```
4189

42-
In addition to the automatic triggers (time delay, scroll position, exit intent), you can also launch a popup by clicking any HTML element (like a link or button) on the page.
90+
### Exit intent trigger
91+
92+
Trigger a popup when the user moves their mouse cursor toward the browser's address bar or tab area, indicating they might be about to leave:
93+
```
94+
[popup show-on-exit-intent]Wait! Don't leave yet. Check out this special offer![/popup]
95+
```
4396

44-
1. **Define the popup:** First, you must have defined the popup on the same page using the shortcode with a unique ID:
97+
*Note: Exit intent only works on desktop/laptop devices with a mouse cursor.*
98+
99+
### Clickable triggers
100+
101+
1. **Define the popup:** First, create a popup with a unique ID:
45102
```
46-
[popup id="my-unique-popup"]Popup content…[/popup]
103+
[popup id="newsletter-signup"]
104+
<h2>Subscribe to our newsletter</h2>
105+
<p>Get weekly updates delivered to your inbox.</p>
106+
[/popup]
107+
```
108+
109+
2. **Create trigger elements:** Add the `data-popup-open` attribute to any HTML element to make it open the popup:
110+
111+
**Text link:**
112+
```html
113+
<a href="#" data-popup-open="newsletter-signup">Subscribe to our newsletter</a>
47114
```
48115

49-
2. **Create the trigger element (link/button):** Next, add an HTML element where you want your trigger. This element must have the data attribute `data-popup-open` set to the ID of the popup you want to open.
116+
**Button:**
117+
```html
118+
<button data-popup-open="newsletter-signup">Sign Up Now</button>
119+
```
50120

51-
**Example using a link:**
121+
**Image:**
52122
```html
53-
<a href="#" data-popup-open="my-unique-popup">Open My Popup</a>
123+
<img src="signup-banner.jpg" data-popup-open="newsletter-signup" alt="Click to subscribe">
54124
```
55125

56-
**Example using a button:**
126+
**Any element:**
57127
```html
58-
<button data-popup-open="my-unique-popup">Open My Popup</button>
128+
<div class="promo-box" data-popup-open="newsletter-signup">
129+
<h3>Special Offer!</h3>
130+
<p>Click anywhere on this box to learn more</p>
131+
</div>
59132
```
60133

61-
When a user clicks the element with `data-popup-open`, the plugin's JavaScript will automatically open the corresponding popup.
134+
*Important:* Both the popup shortcode and trigger elements must exist on the same page.
135+
136+
## Closing popups
62137

63-
*Important:* Both the popup shortcode and the HTML element with `data-popup-open` must exist on the same page.
138+
Kntnt Popup provides several ways for users to close popups, giving you complete control over the user experience.
139+
140+
### Built-in close button
141+
142+
Add a close button (×) in the top-right corner of the popup:
143+
```
144+
[popup close-button]This popup has a close button.[/popup]
145+
```
146+
147+
You can customize the close button character:
148+
```
149+
[popup close-button="✕"]This popup uses a different close icon.[/popup]
150+
```
151+
152+
### Click outside to close
153+
154+
Allow users to close the popup by clicking anywhere outside the popup area:
155+
```
156+
[popup close-outside-click]Click outside this popup to close it.[/popup]
157+
```
158+
159+
### ESC key to close
160+
161+
Enable closing the popup by pressing the ESC key:
162+
```
163+
[popup close-esc-key]Press ESC to close this popup.[/popup]
164+
```
165+
166+
### Custom close triggers
167+
168+
Make any element inside or outside the popup close it by adding the `data-popup-close` attribute:
169+
170+
**Close link inside popup content:**
171+
```
172+
[popup modal show-after-time="5"]
173+
<h2>Welcome!</h2>
174+
<p>Thanks for visiting our site.</p>
175+
<p><a data-popup-close>Close this message</a></p>
176+
[/popup]
177+
```
178+
179+
**Close button inside popup:**
180+
```
181+
[popup show-after-scroll="50"]
182+
<h2>Newsletter Signup</h2>
183+
<form>
184+
<!-- form fields here -->
185+
<button type="submit">Subscribe</button>
186+
<button type="button" data-popup-close>Maybe Later</button>
187+
</form>
188+
[/popup]
189+
```
190+
191+
**External close trigger (anywhere on the page):**
192+
```html
193+
<!-- This button can be anywhere on your page -->
194+
<button data-popup-close>Close any open popup</button>
195+
```
64196

65197
## Parameters
66198

@@ -107,6 +239,7 @@ Controls whether the popup shows after a specified number of seconds.
107239
*Examples:*
108240

109241
* `[popup show-after-time="5"]`: Triggers popup after 5 seconds
242+
* `[popup show-after-time="0"]`: Triggers popup immediately when the page loads
110243
* `[popup show-after-time]`: Triggers popup after 30 seconds (flag value)
111244
* `[popup]`: Won't trigger popup based on time since default value is `false`
112245

@@ -340,6 +473,22 @@ Determines whether clicking outside the popup area closes it.
340473
* `[popup close-outside-click]`: Same as above (using flag value)
341474
* `[popup]`: Clicking outside doesn't close the popup
342475

476+
#### `close-esc-key`
477+
478+
Determines whether pressing the ESC key closes the popup.
479+
480+
*Format:* `close-esc-key=<true|false>`
481+
482+
*Flag value:* `true`
483+
484+
*Default value:* `false`
485+
486+
*Examples:*
487+
488+
* `[popup close-esc-key="true"]`: Popup closes when the ESC key is pressed
489+
* `[popup close-esc-key]`: Same as above (using flag value)
490+
* `[popup]`: Popup does not close when the ESC key is pressed
491+
343492
#### `modal`
344493

345494
Controls whether the popup behaves as a modal dialog.
@@ -493,14 +642,14 @@ Sets the ARIA label for the close button.
493642
```
494643
[popup show-on-exit-intent show-after-time="15" show-after-scroll="60"
495644
position="center" width="600px" overlay-color="rgba(0,0,50,80%)"
496-
close-button modal open-animation="fade-in" close-animation="fade-out"]
645+
close-button modal close-esc-key open-animation="fade-in" close-animation="fade-out"]
497646
<h2>Subscribe to Our Newsletter</h2>
498647
<p>Get the latest updates and special offers delivered directly to your inbox.</p>
499648
[contact-form-7 id="contact-form-12345" title="Newsletter Signup Form"]
500649
[/popup]
501650
```
502651

503-
In this example, the popup will appear when the user tries to leave the page, OR after 15 seconds, OR after scrolling 60% of the page - whichever happens first. It will be centered with a width of 600px, have a dark blue overlay, display a close button, prevent background scrolling, and use fade animations.
652+
In this example, the popup will appear when the user tries to leave the page, OR after 15 seconds, OR after scrolling 60% of the page - whichever happens first. It will be centered with a width of 600px, have a dark blue overlay, display a close button, allow ESC key closing, prevent background scrolling, and use fade animations.
504653

505654
### Examples
506655

@@ -720,6 +869,13 @@ If you are not familiar with Git, please create a new ticket on the plugin's iss
720869
721870
## Changelog
722871
872+
## 1.1.0 (2025-05-23)
873+
874+
- feature: add new `close-esc-key` parameter to control whether ESC key closes the popup
875+
- enhance: improve documentation with better examples and clearer usage instructions
876+
- enhance: add acknowledgment of Micromodal.js library
877+
- improve: reorganize README structure for better navigation
878+
723879
## 1.0.2 (2025-05-23)
724880
725881
- fix: resolve JavaScript initialization timing issue that prevented popups from working
@@ -730,7 +886,7 @@ If you are not familiar with Git, please create a new ticket on the plugin's iss
730886
731887
- fix: show-after-time=0 works
732888
- fix: functions works in css
733-
- fix: correct aria is used
889+
- fix: correct aria is used
734890
735891
## 1.0.0 (2025-05-22)
736892

classes/shortcode.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public function __construct() {
5555
'show-after-scroll' => false,
5656
'close-button' => false,
5757
'close-outside-click' => false,
58+
'close-esc-key' => false,
5859
'reappear-delay' => 0,
5960
'modal' => false,
6061
'overlay-color' => 'rgba(0,0,0,0.8)',
@@ -82,6 +83,7 @@ public function __construct() {
8283
'show-after-scroll' => 80, // percent
8384
'close-button' => '', // HTML entity for multiplication sign
8485
'close-outside-click' => true,
86+
'close-esc-key' => true,
8587
'reappear-delay' => '1d', // 1 day
8688
'modal' => true,
8789
'open-animation' => 'tada',
@@ -169,6 +171,7 @@ public function handle_shortcode( mixed $raw_attributes, ?string $content = null
169171
'showAfterScroll' => $validated_attributes['show-after-scroll'],
170172
'closeButton' => $validated_attributes['close-button'] !== false,
171173
'closeOutsideClick' => $validated_attributes['close-outside-click'],
174+
'closeEscKey' => $validated_attributes['close-esc-key'],
172175
'reappearDelay' => $validated_attributes['reappear-delay'],
173176
'isModal' => $validated_attributes['modal'],
174177
'openAnimation' => $validated_attributes['open-animation'],
@@ -285,6 +288,7 @@ private function sanitize_and_validate_attributes( array $processed_attributes )
285288
// Sanitize boolean attributes using filter_var.
286289
$validated['show-on-exit-intent'] = filter_var( $processed_attributes['show-on-exit-intent'], FILTER_VALIDATE_BOOLEAN );
287290
$validated['close-outside-click'] = filter_var( $processed_attributes['close-outside-click'], FILTER_VALIDATE_BOOLEAN );
291+
$validated['close-esc-key'] = filter_var( $processed_attributes['close-esc-key'], FILTER_VALIDATE_BOOLEAN );
288292
$validated['modal'] = filter_var( $processed_attributes['modal'], FILTER_VALIDATE_BOOLEAN );
289293

290294
// Sanitize 'show-after-time': integer (seconds) or false.
@@ -597,4 +601,4 @@ function cleanup_wp_mess( $content ) {
597601

598602
}
599603

600-
}
604+
}

js/kntnt-popup.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* It relies on the Micromodal.js library for modal functionality and kntntPopupData (localized from PHP)
66
* for popup configurations.
77
*
8-
* @version 1.0.0
8+
* @version 1.1.0
99
* @param {Window} window - The global window object.
1010
* @param {Document} document - The global document object.
1111
* @param {object} MicroModal - The MicroModal library instance.
@@ -35,6 +35,19 @@
3535
let exitIntentListenerAttached = false
3636
const exitIntentPopups = []
3737
const STORAGE_PREFIX = 'kntnt_popup_last_closed_'
38+
const activeEscKeyListeners = {}
39+
40+
/**
41+
* Prevents the ESC key from closing a modal when closeEscKey is false.
42+
*
43+
* @param {KeyboardEvent} event - The keyboard event.
44+
*/
45+
const preventEscapeKey = (event) => {
46+
if (event.key === 'Escape') {
47+
event.preventDefault()
48+
event.stopPropagation()
49+
}
50+
}
3851

3952
/**
4053
* Retrieves the animation duration for a popup opening or closing.
@@ -217,18 +230,34 @@
217230
dispatchCustomEvent('kntnt_popup:before_open', popupId)
218231
MicroModal.show(popupId, {
219232
onShow: (modal) => {
233+
220234
if (!modal) return
221235
const dialog = modal.querySelector('.kntnt-popup__dialog')
222236
if (!dialog) return
223237
setupModalAnimations(modal, dialog, config, 'open')
224238
modal.removeAttribute('data-close-animation')
225239
dialog.style.removeProperty('--kntnt-popup-close-duration')
240+
241+
// Handle ESC key behavior based on configuration
242+
if (!config.closeEscKey) {
243+
document.addEventListener('keydown', preventEscapeKey, true)
244+
activeEscKeyListeners[popupId] = true
245+
}
246+
226247
dispatchCustomEvent('kntnt_popup:after_open', popupId)
248+
227249
},
228250
onClose: (modal) => {
229251
if (!modal) return
230252
storeCloseTimestamp(popupId)
231253
const dialog = modal.querySelector('.kntnt-popup__dialog')
254+
255+
// Remove ESC key prevention if it was active
256+
if (activeEscKeyListeners[popupId]) {
257+
document.removeEventListener('keydown', preventEscapeKey, true)
258+
delete activeEscKeyListeners[popupId]
259+
}
260+
232261
if (!dialog) {
233262
dispatchCustomEvent('kntnt_popup:after_close', popupId)
234263
return

kntnt-popup.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Plugin Name: Kntnt Popup
44
* Plugin URI: https://github.com/Kntnt/kntnt-popup
55
* Description: Provides shortcode for creating popups
6-
* Version: 1.0.2
6+
* Version: 1.1.0
77
* Requires at least: 6.8
88
* Requires PHP: 8.2
99
* Author: TBarregren

0 commit comments

Comments
 (0)