toastify-pro 1.4.0 → 1.5.0
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.
- package/dist/toastify-pro.esm.js +253 -4
- package/dist/toastify-pro.esm.js.map +1 -1
- package/dist/toastify-pro.umd.js +253 -4
- package/dist/toastify-pro.umd.js.map +1 -1
- package/dist/toastify-pro.umd.min.js +4 -5
- package/dist/toastify-pro.umd.min.js.map +1 -1
- package/package.json +2 -2
- package/src/toastify-pro.js +253 -4
package/dist/toastify-pro.esm.js
CHANGED
|
@@ -9,17 +9,16 @@
|
|
|
9
9
|
* - Position-aware car swipe exit animations
|
|
10
10
|
* - Description support for enhanced messaging
|
|
11
11
|
* - Six theme variants (success, error, info, warning, dark, light)
|
|
12
|
+
* - Custom color toasts with gradient support (custom method)
|
|
12
13
|
* - Progress bar with shimmer effects
|
|
13
14
|
* - Responsive design for mobile devices
|
|
14
15
|
* - Framework agnostic (works with React, Vue, Angular, etc.)
|
|
15
16
|
* - Confirmation dialogs with customizable buttons and callbacks
|
|
17
|
+
* - Confirmation overlay with blur effect for focus
|
|
16
18
|
* - Center position support for enhanced focus
|
|
17
19
|
* - Independent positioning for confirmations
|
|
18
|
-
* - Loading states for async operations
|
|
19
|
-
* - Custom gradient colors with primaryColor/secondaryColor
|
|
20
|
-
* - Single instance mode with shake animation
|
|
21
20
|
*
|
|
22
|
-
* @version 1.
|
|
21
|
+
* @version 1.5.0
|
|
23
22
|
* @author ToastifyPro Team
|
|
24
23
|
* @license MIT
|
|
25
24
|
*/
|
|
@@ -35,6 +34,8 @@ class ToastifyPro {
|
|
|
35
34
|
* @param {number} options.timeout - Auto-dismiss timeout in milliseconds (0 to disable)
|
|
36
35
|
* @param {boolean} options.allowClose - Whether to show close button
|
|
37
36
|
* @param {number} options.maxLength - Maximum message length
|
|
37
|
+
* @param {string} options.primaryColor - Primary color for custom() method
|
|
38
|
+
* @param {string} options.secondaryColor - Secondary color for gradient in custom() method
|
|
38
39
|
*/
|
|
39
40
|
constructor(options = {}) {
|
|
40
41
|
// Validate options parameter
|
|
@@ -49,6 +50,8 @@ class ToastifyPro {
|
|
|
49
50
|
timeout: options.timeout || 3000,
|
|
50
51
|
allowClose: options.allowClose !== false, // default true
|
|
51
52
|
maxLength: options.maxLength || 100,
|
|
53
|
+
primaryColor: options.primaryColor || null, // Custom primary color for custom() method
|
|
54
|
+
secondaryColor: options.secondaryColor || null, // Custom secondary color for gradient
|
|
52
55
|
};
|
|
53
56
|
|
|
54
57
|
// Validate position
|
|
@@ -793,6 +796,58 @@ class ToastifyPro {
|
|
|
793
796
|
max-width: calc(100vw - 32px);
|
|
794
797
|
}
|
|
795
798
|
}
|
|
799
|
+
|
|
800
|
+
/* Custom toast type */
|
|
801
|
+
.toastify-pro.custom {
|
|
802
|
+
border-color: rgba(255, 255, 255, 0.2);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.toastify-pro.custom.light-text {
|
|
806
|
+
color: #1e293b;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
.toastify-pro.custom.light-text .toast-icon {
|
|
810
|
+
background: rgba(15, 23, 42, 0.1);
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
.toastify-pro.custom.light-text .close-btn {
|
|
814
|
+
background: rgba(15, 23, 42, 0.08);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
.toastify-pro.custom.light-text .close-btn:hover {
|
|
818
|
+
background: rgba(15, 23, 42, 0.15);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
.toastify-pro.custom.light-text::before {
|
|
822
|
+
background: linear-gradient(90deg,
|
|
823
|
+
rgba(30, 41, 59, 0.8) 0%,
|
|
824
|
+
rgba(30, 41, 59, 0.4) 50%,
|
|
825
|
+
rgba(30, 41, 59, 0.8) 100%);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
.toastify-pro.custom.light-text::after {
|
|
829
|
+
background: rgba(30, 41, 59, 0.6);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/* Confirmation Overlay */
|
|
833
|
+
.toastify-pro-overlay {
|
|
834
|
+
position: fixed;
|
|
835
|
+
top: 0;
|
|
836
|
+
left: 0;
|
|
837
|
+
right: 0;
|
|
838
|
+
bottom: 0;
|
|
839
|
+
background: rgba(0, 0, 0, 0.5);
|
|
840
|
+
backdrop-filter: blur(8px);
|
|
841
|
+
-webkit-backdrop-filter: blur(8px);
|
|
842
|
+
z-index: 9998;
|
|
843
|
+
opacity: 0;
|
|
844
|
+
transition: opacity 0.3s ease;
|
|
845
|
+
pointer-events: auto;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
.toastify-pro-overlay.show {
|
|
849
|
+
opacity: 1;
|
|
850
|
+
}
|
|
796
851
|
`;
|
|
797
852
|
document.head.appendChild(style);
|
|
798
853
|
} catch (error) {
|
|
@@ -1034,6 +1089,168 @@ class ToastifyPro {
|
|
|
1034
1089
|
this.show(msg, "light", opts);
|
|
1035
1090
|
}
|
|
1036
1091
|
|
|
1092
|
+
/**
|
|
1093
|
+
* Shows a custom-colored toast notification with gradient support
|
|
1094
|
+
* @param {string} msg - Main message
|
|
1095
|
+
* @param {string|Object} opts - Description string or options object
|
|
1096
|
+
* @param {string} opts.primaryColor - Primary color for the toast
|
|
1097
|
+
* @param {string} opts.secondaryColor - Secondary color for gradient (optional)
|
|
1098
|
+
*/
|
|
1099
|
+
custom(msg, opts) {
|
|
1100
|
+
if (typeof opts === 'string') {
|
|
1101
|
+
opts = { description: opts };
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
opts = opts || {};
|
|
1105
|
+
|
|
1106
|
+
// Get colors from options or use default options
|
|
1107
|
+
const primaryColor = opts.primaryColor || this.defaultOptions.primaryColor;
|
|
1108
|
+
const secondaryColor = opts.secondaryColor || this.defaultOptions.secondaryColor;
|
|
1109
|
+
|
|
1110
|
+
// If no custom colors provided, fallback to success style
|
|
1111
|
+
if (!primaryColor) {
|
|
1112
|
+
return this.success(msg, opts);
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
// Helper function to determine if a color is light
|
|
1116
|
+
const isLightColor = (color) => {
|
|
1117
|
+
if (!color) return false;
|
|
1118
|
+
const hex = color.replace('#', '');
|
|
1119
|
+
const r = parseInt(hex.substr(0, 2), 16);
|
|
1120
|
+
const g = parseInt(hex.substr(2, 2), 16);
|
|
1121
|
+
const b = parseInt(hex.substr(4, 2), 16);
|
|
1122
|
+
const brightness = ((r * 299) + (g * 587) + (b * 114)) / 1000;
|
|
1123
|
+
return brightness > 155;
|
|
1124
|
+
};
|
|
1125
|
+
|
|
1126
|
+
// Helper function to lighten or darken a color
|
|
1127
|
+
const adjustColor = (color, percent) => {
|
|
1128
|
+
const hex = color.replace('#', '');
|
|
1129
|
+
const r = parseInt(hex.substr(0, 2), 16);
|
|
1130
|
+
const g = parseInt(hex.substr(2, 2), 16);
|
|
1131
|
+
const b = parseInt(hex.substr(4, 2), 16);
|
|
1132
|
+
|
|
1133
|
+
const adjust = (c) => {
|
|
1134
|
+
const adjusted = Math.round(c + (percent / 100) * (percent > 0 ? (255 - c) : c));
|
|
1135
|
+
return Math.max(0, Math.min(255, adjusted));
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
const newR = adjust(r).toString(16).padStart(2, '0');
|
|
1139
|
+
const newG = adjust(g).toString(16).padStart(2, '0');
|
|
1140
|
+
const newB = adjust(b).toString(16).padStart(2, '0');
|
|
1141
|
+
|
|
1142
|
+
return `#${newR}${newG}${newB}`;
|
|
1143
|
+
};
|
|
1144
|
+
|
|
1145
|
+
// Determine gradient colors
|
|
1146
|
+
let gradientStart = primaryColor;
|
|
1147
|
+
let gradientEnd;
|
|
1148
|
+
|
|
1149
|
+
if (secondaryColor) {
|
|
1150
|
+
// Both colors provided
|
|
1151
|
+
gradientEnd = secondaryColor;
|
|
1152
|
+
} else {
|
|
1153
|
+
// Only primary color - create gradient with lighter/darker shade
|
|
1154
|
+
const isLight = isLightColor(primaryColor);
|
|
1155
|
+
gradientEnd = isLight ? adjustColor(primaryColor, -25) : adjustColor(primaryColor, 25);
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// Determine text color
|
|
1159
|
+
const needsLightText = isLightColor(primaryColor);
|
|
1160
|
+
|
|
1161
|
+
// Create custom options
|
|
1162
|
+
const customOpts = {
|
|
1163
|
+
...opts,
|
|
1164
|
+
customGradient: `linear-gradient(135deg, ${gradientStart} 0%, ${gradientEnd} 100%)`,
|
|
1165
|
+
customTextLight: needsLightText
|
|
1166
|
+
};
|
|
1167
|
+
|
|
1168
|
+
this.showCustom(msg, customOpts);
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
/**
|
|
1172
|
+
* Internal method to show a custom-styled toast
|
|
1173
|
+
* @param {string} message - Main message text
|
|
1174
|
+
* @param {Object} opts - Options including customGradient and customTextLight
|
|
1175
|
+
*/
|
|
1176
|
+
showCustom(message, opts = {}) {
|
|
1177
|
+
if (typeof message !== 'string') {
|
|
1178
|
+
message = String(message);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
if (!message.trim()) {
|
|
1182
|
+
console.warn('ToastifyPro: Empty message provided.');
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
const options = { ...this.defaultOptions, ...opts };
|
|
1187
|
+
|
|
1188
|
+
try {
|
|
1189
|
+
const toast = document.createElement("div");
|
|
1190
|
+
toast.className = `toastify-pro custom${options.customTextLight ? ' light-text' : ''}`;
|
|
1191
|
+
|
|
1192
|
+
// Apply custom gradient
|
|
1193
|
+
if (options.customGradient) {
|
|
1194
|
+
toast.style.background = options.customGradient;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
if (options.timeout > 0) {
|
|
1198
|
+
toast.style.setProperty('--duration', `${options.timeout}ms`);
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
// Create icon wrapper
|
|
1202
|
+
const iconWrapper = document.createElement("div");
|
|
1203
|
+
iconWrapper.className = "toast-icon";
|
|
1204
|
+
iconWrapper.innerHTML = this.getIconSVG('success'); // Use success icon for custom
|
|
1205
|
+
toast.appendChild(iconWrapper);
|
|
1206
|
+
|
|
1207
|
+
// Create content wrapper
|
|
1208
|
+
const contentWrapper = document.createElement("div");
|
|
1209
|
+
contentWrapper.className = "toast-content";
|
|
1210
|
+
|
|
1211
|
+
const messageElement = document.createElement("div");
|
|
1212
|
+
messageElement.className = "toast-message";
|
|
1213
|
+
messageElement.textContent = message.substring(0, options.maxLength);
|
|
1214
|
+
contentWrapper.appendChild(messageElement);
|
|
1215
|
+
|
|
1216
|
+
if (options.description && typeof options.description === 'string') {
|
|
1217
|
+
const descriptionElement = document.createElement("div");
|
|
1218
|
+
descriptionElement.className = "toast-description";
|
|
1219
|
+
descriptionElement.textContent = options.description.substring(0, options.maxLength * 2);
|
|
1220
|
+
contentWrapper.appendChild(descriptionElement);
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
toast.appendChild(contentWrapper);
|
|
1224
|
+
|
|
1225
|
+
if (options.allowClose) {
|
|
1226
|
+
const closeBtn = document.createElement("span");
|
|
1227
|
+
closeBtn.className = "close-btn";
|
|
1228
|
+
closeBtn.innerHTML = "×";
|
|
1229
|
+
closeBtn.setAttribute('aria-label', 'Close notification');
|
|
1230
|
+
closeBtn.onclick = () => this.removeToast(toast);
|
|
1231
|
+
toast.appendChild(closeBtn);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
this.container.appendChild(toast);
|
|
1235
|
+
|
|
1236
|
+
setTimeout(() => {
|
|
1237
|
+
toast.classList.add("show");
|
|
1238
|
+
const icon = toast.querySelector('.toast-icon');
|
|
1239
|
+
if (icon) {
|
|
1240
|
+
icon.style.animation = 'iconBounce 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275)';
|
|
1241
|
+
}
|
|
1242
|
+
}, 10);
|
|
1243
|
+
|
|
1244
|
+
if (options.timeout > 0) {
|
|
1245
|
+
setTimeout(() => this.removeToast(toast), options.timeout);
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
return toast;
|
|
1249
|
+
} catch (error) {
|
|
1250
|
+
console.error('ToastifyPro: Failed to create custom toast:', error);
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1037
1254
|
/**
|
|
1038
1255
|
* Shows a confirmation toast with confirm/cancel buttons
|
|
1039
1256
|
* @param {string} message - Main confirmation question
|
|
@@ -1161,6 +1378,34 @@ class ToastifyPro {
|
|
|
1161
1378
|
let isLoading = false;
|
|
1162
1379
|
let useLoading = false; // Track if user wants loading behavior
|
|
1163
1380
|
let toastElement = null; // Reference to toast element
|
|
1381
|
+
let overlayElement = null; // Reference to overlay element
|
|
1382
|
+
|
|
1383
|
+
// Create overlay for confirmation
|
|
1384
|
+
const createOverlay = () => {
|
|
1385
|
+
overlayElement = document.createElement("div");
|
|
1386
|
+
overlayElement.className = "toastify-pro-overlay";
|
|
1387
|
+
document.body.appendChild(overlayElement);
|
|
1388
|
+
|
|
1389
|
+
// Trigger show animation
|
|
1390
|
+
setTimeout(() => {
|
|
1391
|
+
overlayElement.classList.add("show");
|
|
1392
|
+
}, 10);
|
|
1393
|
+
|
|
1394
|
+
return overlayElement;
|
|
1395
|
+
};
|
|
1396
|
+
|
|
1397
|
+
// Remove overlay
|
|
1398
|
+
const removeOverlay = () => {
|
|
1399
|
+
if (overlayElement && overlayElement.parentNode) {
|
|
1400
|
+
overlayElement.classList.remove("show");
|
|
1401
|
+
setTimeout(() => {
|
|
1402
|
+
if (overlayElement && overlayElement.parentNode) {
|
|
1403
|
+
overlayElement.remove();
|
|
1404
|
+
}
|
|
1405
|
+
overlayElement = null;
|
|
1406
|
+
}, 300);
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1164
1409
|
|
|
1165
1410
|
const setLoading = (loading) => {
|
|
1166
1411
|
useLoading = true; // User is manually controlling loading
|
|
@@ -1190,6 +1435,7 @@ class ToastifyPro {
|
|
|
1190
1435
|
const closeConfirmation = () => {
|
|
1191
1436
|
if (toastElement && toastElement.parentNode) {
|
|
1192
1437
|
globalActiveConfirmation = null;
|
|
1438
|
+
removeOverlay(); // Remove the overlay when closing
|
|
1193
1439
|
this.removeToast(toastElement);
|
|
1194
1440
|
}
|
|
1195
1441
|
};
|
|
@@ -1277,6 +1523,9 @@ class ToastifyPro {
|
|
|
1277
1523
|
};
|
|
1278
1524
|
|
|
1279
1525
|
try {
|
|
1526
|
+
// Create overlay first
|
|
1527
|
+
createOverlay();
|
|
1528
|
+
|
|
1280
1529
|
// Create confirmation toast element
|
|
1281
1530
|
const toast = document.createElement("div");
|
|
1282
1531
|
toast.className = `toastify-pro confirmation ${confirmOptions.theme}`;
|