|
@@ -150,7 +150,159 @@
|
|
|
transform-origin: center;
|
|
transform-origin: center;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- .${PREFIX}icon.success { color: #a5dc86; }
|
|
|
|
|
|
|
+ /* =========================================
|
|
|
|
|
+ SweetAlert2-compatible SUCCESS icon (DOM)
|
|
|
|
|
+ (matches sweetalert2 v11.26.17)
|
|
|
|
|
+ ========================================= */
|
|
|
|
|
+ .${PREFIX}icon.success {
|
|
|
|
|
+ /* Override the generic SVG icon box */
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ place-items: initial;
|
|
|
|
|
+ box-sizing: content-box;
|
|
|
|
|
+ width: 5em;
|
|
|
|
|
+ height: 5em;
|
|
|
|
|
+ margin: 2.5em auto 0.6em;
|
|
|
|
|
+ border: 0.25em solid rgba(0, 0, 0, 0);
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ border-color: #a5dc86;
|
|
|
|
|
+ color: #a5dc86;
|
|
|
|
|
+ font-family: inherit;
|
|
|
|
|
+ line-height: 5em;
|
|
|
|
|
+ cursor: default;
|
|
|
|
|
+ user-select: none;
|
|
|
|
|
+ }
|
|
|
|
|
+ .${PREFIX}icon.success .${PREFIX}success-ring {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ z-index: 2;
|
|
|
|
|
+ top: -0.25em;
|
|
|
|
|
+ left: -0.25em;
|
|
|
|
|
+ box-sizing: content-box;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ border: 0.25em solid rgba(165, 220, 134, 0.3);
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ }
|
|
|
|
|
+ .${PREFIX}icon.success .${PREFIX}success-fix {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ z-index: 1;
|
|
|
|
|
+ top: 0.5em;
|
|
|
|
|
+ left: 1.625em;
|
|
|
|
|
+ width: 0.4375em;
|
|
|
|
|
+ height: 5.625em;
|
|
|
|
|
+ transform: rotate(-45deg);
|
|
|
|
|
+ background-color: #fff; /* adjusted at runtime to popup bg */
|
|
|
|
|
+ }
|
|
|
|
|
+ .${PREFIX}icon.success .${PREFIX}success-circular-line-left,
|
|
|
|
|
+ .${PREFIX}icon.success .${PREFIX}success-circular-line-right {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ width: 3.75em;
|
|
|
|
|
+ height: 7.5em;
|
|
|
|
|
+ border-radius: 50%;
|
|
|
|
|
+ background-color: #fff; /* adjusted at runtime to popup bg */
|
|
|
|
|
+ }
|
|
|
|
|
+ .${PREFIX}icon.success .${PREFIX}success-circular-line-left {
|
|
|
|
|
+ top: -0.4375em;
|
|
|
|
|
+ left: -2.0635em;
|
|
|
|
|
+ transform: rotate(-45deg);
|
|
|
|
|
+ transform-origin: 3.75em 3.75em;
|
|
|
|
|
+ border-radius: 7.5em 0 0 7.5em;
|
|
|
|
|
+ }
|
|
|
|
|
+ .${PREFIX}icon.success .${PREFIX}success-circular-line-right {
|
|
|
|
|
+ top: -0.6875em;
|
|
|
|
|
+ left: 1.875em;
|
|
|
|
|
+ transform: rotate(-45deg);
|
|
|
|
|
+ transform-origin: 0 3.75em;
|
|
|
|
|
+ border-radius: 0 7.5em 7.5em 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ .${PREFIX}icon.success .${PREFIX}success-line-tip,
|
|
|
|
|
+ .${PREFIX}icon.success .${PREFIX}success-line-long {
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ z-index: 2;
|
|
|
|
|
+ height: 0.3125em;
|
|
|
|
|
+ border-radius: 0.125em;
|
|
|
|
|
+ background-color: #a5dc86;
|
|
|
|
|
+ }
|
|
|
|
|
+ .${PREFIX}icon.success .${PREFIX}success-line-tip {
|
|
|
|
|
+ top: 2.875em;
|
|
|
|
|
+ left: 0.8125em;
|
|
|
|
|
+ width: 1.5625em;
|
|
|
|
|
+ transform: rotate(45deg);
|
|
|
|
|
+ }
|
|
|
|
|
+ .${PREFIX}icon.success .${PREFIX}success-line-long {
|
|
|
|
|
+ top: 2.375em;
|
|
|
|
|
+ right: 0.5em;
|
|
|
|
|
+ width: 2.9375em;
|
|
|
|
|
+ transform: rotate(-45deg);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* Triggered when icon has .${PREFIX}icon-show */
|
|
|
|
|
+ .${PREFIX}icon.success.${PREFIX}icon-show .${PREFIX}success-line-tip {
|
|
|
|
|
+ animation: ${PREFIX}animate-success-line-tip 0.75s;
|
|
|
|
|
+ }
|
|
|
|
|
+ .${PREFIX}icon.success.${PREFIX}icon-show .${PREFIX}success-line-long {
|
|
|
|
|
+ animation: ${PREFIX}animate-success-line-long 0.75s;
|
|
|
|
|
+ }
|
|
|
|
|
+ .${PREFIX}icon.success.${PREFIX}icon-show .${PREFIX}success-circular-line-right {
|
|
|
|
|
+ animation: ${PREFIX}rotate-success-circular-line 4.25s ease-in;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @keyframes ${PREFIX}animate-success-line-tip {
|
|
|
|
|
+ 0% {
|
|
|
|
|
+ top: 1.1875em;
|
|
|
|
|
+ left: 0.0625em;
|
|
|
|
|
+ width: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ 54% {
|
|
|
|
|
+ top: 1.0625em;
|
|
|
|
|
+ left: 0.125em;
|
|
|
|
|
+ width: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ 70% {
|
|
|
|
|
+ top: 2.1875em;
|
|
|
|
|
+ left: -0.375em;
|
|
|
|
|
+ width: 3.125em;
|
|
|
|
|
+ }
|
|
|
|
|
+ 84% {
|
|
|
|
|
+ top: 3em;
|
|
|
|
|
+ left: 1.3125em;
|
|
|
|
|
+ width: 1.0625em;
|
|
|
|
|
+ }
|
|
|
|
|
+ 100% {
|
|
|
|
|
+ top: 2.8125em;
|
|
|
|
|
+ left: 0.8125em;
|
|
|
|
|
+ width: 1.5625em;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ @keyframes ${PREFIX}animate-success-line-long {
|
|
|
|
|
+ 0% {
|
|
|
|
|
+ top: 3.375em;
|
|
|
|
|
+ right: 2.875em;
|
|
|
|
|
+ width: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ 65% {
|
|
|
|
|
+ top: 3.375em;
|
|
|
|
|
+ right: 2.875em;
|
|
|
|
|
+ width: 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ 84% {
|
|
|
|
|
+ top: 2.1875em;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ width: 3.4375em;
|
|
|
|
|
+ }
|
|
|
|
|
+ 100% {
|
|
|
|
|
+ top: 2.375em;
|
|
|
|
|
+ right: 0.5em;
|
|
|
|
|
+ width: 2.9375em;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ @keyframes ${PREFIX}rotate-success-circular-line {
|
|
|
|
|
+ 0% { transform: rotate(-45deg); }
|
|
|
|
|
+ 5% { transform: rotate(-45deg); }
|
|
|
|
|
+ 12% { transform: rotate(-405deg); }
|
|
|
|
|
+ 100% { transform: rotate(-405deg); }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
.${PREFIX}icon.error { color: #f27474; }
|
|
.${PREFIX}icon.error { color: #f27474; }
|
|
|
.${PREFIX}icon.warning { color: #f8bb86; }
|
|
.${PREFIX}icon.warning { color: #f8bb86; }
|
|
|
.${PREFIX}icon.info { color: #3fc3ee; }
|
|
.${PREFIX}icon.info { color: #3fc3ee; }
|
|
@@ -348,18 +500,66 @@
|
|
|
const icon = document.createElement('div');
|
|
const icon = document.createElement('div');
|
|
|
icon.className = `${PREFIX}icon ${type}`;
|
|
icon.className = `${PREFIX}icon ${type}`;
|
|
|
|
|
|
|
|
- // Allow per-popup icon sizing (overrides CSS default)
|
|
|
|
|
- if (this.params && this.params.iconSize) {
|
|
|
|
|
|
|
+ const applyIconSize = (mode) => {
|
|
|
|
|
+ if (!(this.params && this.params.iconSize)) return;
|
|
|
try {
|
|
try {
|
|
|
- const s = String(this.params.iconSize).trim();
|
|
|
|
|
- if (s) {
|
|
|
|
|
- icon.style.width = s;
|
|
|
|
|
- icon.style.height = s;
|
|
|
|
|
|
|
+ const raw = this.params.iconSize;
|
|
|
|
|
+ const s = String(raw).trim();
|
|
|
|
|
+ if (!s) return;
|
|
|
|
|
+ // For SweetAlert2-style success icon, scale via font-size so all `em`-based
|
|
|
|
|
+ // parts remain proportional.
|
|
|
|
|
+ if (mode === 'font') {
|
|
|
|
|
+ const m = s.match(/^(-?\d*\.?\d+)\s*(px|em|rem)$/i);
|
|
|
|
|
+ if (m) {
|
|
|
|
|
+ const n = parseFloat(m[1]);
|
|
|
|
|
+ const unit = m[2];
|
|
|
|
|
+ if (Number.isFinite(n) && n > 0) {
|
|
|
|
|
+ icon.style.fontSize = (n / 5) + unit; // icon is 5em wide/tall
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+ // Fallback: directly size the box (works great for SVG icons)
|
|
|
|
|
+ icon.style.width = s;
|
|
|
|
|
+ icon.style.height = s;
|
|
|
} catch {}
|
|
} catch {}
|
|
|
- }
|
|
|
|
|
|
|
+ };
|
|
|
|
|
|
|
|
const svgNs = 'http://www.w3.org/2000/svg';
|
|
const svgNs = 'http://www.w3.org/2000/svg';
|
|
|
|
|
+ if (type === 'success') {
|
|
|
|
|
+ // SweetAlert2-compatible DOM structure (circle + tick) for exact style parity
|
|
|
|
|
+ // <div class="...success-circular-line-left"></div>
|
|
|
|
|
+ // <span class="...success-line-tip"></span>
|
|
|
|
|
+ // <span class="...success-line-long"></span>
|
|
|
|
|
+ // <div class="...success-ring"></div>
|
|
|
|
|
+ // <div class="...success-fix"></div>
|
|
|
|
|
+ // <div class="...success-circular-line-right"></div>
|
|
|
|
|
+ const left = document.createElement('div');
|
|
|
|
|
+ left.className = `${PREFIX}success-circular-line-left`;
|
|
|
|
|
+ const tip = document.createElement('span');
|
|
|
|
|
+ tip.className = `${PREFIX}success-line-tip`;
|
|
|
|
|
+ const long = document.createElement('span');
|
|
|
|
|
+ long.className = `${PREFIX}success-line-long`;
|
|
|
|
|
+ const ring = document.createElement('div');
|
|
|
|
|
+ ring.className = `${PREFIX}success-ring`;
|
|
|
|
|
+ const fix = document.createElement('div');
|
|
|
|
|
+ fix.className = `${PREFIX}success-fix`;
|
|
|
|
|
+ const right = document.createElement('div');
|
|
|
|
|
+ right.className = `${PREFIX}success-circular-line-right`;
|
|
|
|
|
+ icon.appendChild(left);
|
|
|
|
|
+ icon.appendChild(tip);
|
|
|
|
|
+ icon.appendChild(long);
|
|
|
|
|
+ icon.appendChild(ring);
|
|
|
|
|
+ icon.appendChild(fix);
|
|
|
|
|
+ icon.appendChild(right);
|
|
|
|
|
+
|
|
|
|
|
+ applyIconSize('font');
|
|
|
|
|
+ return icon;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Default to SVG icons for other types
|
|
|
|
|
+ applyIconSize('box');
|
|
|
|
|
+
|
|
|
const svg = document.createElementNS(svgNs, 'svg');
|
|
const svg = document.createElementNS(svgNs, 'svg');
|
|
|
svg.setAttribute('viewBox', '0 0 80 80');
|
|
svg.setAttribute('viewBox', '0 0 80 80');
|
|
|
svg.setAttribute('aria-hidden', 'true');
|
|
svg.setAttribute('aria-hidden', 'true');
|
|
@@ -383,9 +583,7 @@
|
|
|
return p;
|
|
return p;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- if (type === 'success') {
|
|
|
|
|
- addPath('M23 41 L34.5 53 L58 29', `${PREFIX}svg-success`);
|
|
|
|
|
- } else if (type === 'error') {
|
|
|
|
|
|
|
+ if (type === 'error') {
|
|
|
addPath('M28 28 L52 52', `${PREFIX}svg-error-left`);
|
|
addPath('M28 28 L52 52', `${PREFIX}svg-error-left`);
|
|
|
addPath('M52 28 L28 52', `${PREFIX}svg-error-right`);
|
|
addPath('M52 28 L28 52', `${PREFIX}svg-error-right`);
|
|
|
} else if (type === 'warning') {
|
|
} else if (type === 'warning') {
|
|
@@ -417,7 +615,7 @@
|
|
|
dot.setAttribute('fill', 'currentColor');
|
|
dot.setAttribute('fill', 'currentColor');
|
|
|
svg.appendChild(dot);
|
|
svg.appendChild(dot);
|
|
|
} else {
|
|
} else {
|
|
|
- // Fallback to info-like ring only
|
|
|
|
|
|
|
+ // Fallback: ring only
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
icon.appendChild(svg);
|
|
icon.appendChild(svg);
|
|
@@ -425,6 +623,20 @@
|
|
|
return icon;
|
|
return icon;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ _adjustSuccessIconBackgroundColor() {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const icon = this.dom && this.dom.icon;
|
|
|
|
|
+ const popup = this.dom && this.dom.popup;
|
|
|
|
|
+ if (!icon || !popup) return;
|
|
|
|
|
+ if (!(icon.classList && icon.classList.contains('success'))) return;
|
|
|
|
|
+ const bg = getComputedStyle(popup).backgroundColor;
|
|
|
|
|
+ const parts = icon.querySelectorAll(`.${PREFIX}success-circular-line-left, .${PREFIX}success-circular-line-right, .${PREFIX}success-fix`);
|
|
|
|
|
+ parts.forEach((el) => {
|
|
|
|
|
+ try { el.style.backgroundColor = bg; } catch {}
|
|
|
|
|
+ });
|
|
|
|
|
+ } catch {}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
_didOpen() {
|
|
_didOpen() {
|
|
|
// Keyboard close (ESC)
|
|
// Keyboard close (ESC)
|
|
|
if (this.params.closeOnEsc) {
|
|
if (this.params.closeOnEsc) {
|
|
@@ -435,6 +647,9 @@
|
|
|
document.addEventListener('keydown', this._onKeydown);
|
|
document.addEventListener('keydown', this._onKeydown);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // Keep SweetAlert2 success icon perfectly blended with popup bg
|
|
|
|
|
+ this._adjustSuccessIconBackgroundColor();
|
|
|
|
|
+
|
|
|
// Popup animation (optional)
|
|
// Popup animation (optional)
|
|
|
if (this.params.popupAnimation) {
|
|
if (this.params.popupAnimation) {
|
|
|
const X = Layer._getXjs();
|
|
const X = Layer._getXjs();
|
|
@@ -468,10 +683,21 @@
|
|
|
const icon = this.dom.icon;
|
|
const icon = this.dom.icon;
|
|
|
if (!icon) return;
|
|
if (!icon) return;
|
|
|
const X = Layer._getXjs();
|
|
const X = Layer._getXjs();
|
|
|
- if (!X) return;
|
|
|
|
|
-
|
|
|
|
|
const type = (this.params && this.params.icon) || '';
|
|
const type = (this.params && this.params.icon) || '';
|
|
|
|
|
|
|
|
|
|
+ // SweetAlert2-style success icon uses pure CSS keyframes; keep the look identical.
|
|
|
|
|
+ if (type === 'success') {
|
|
|
|
|
+ this._adjustSuccessIconBackgroundColor();
|
|
|
|
|
+ // Force restart by removing/adding the class
|
|
|
|
|
+ try { icon.classList.remove(`${PREFIX}icon-show`); } catch {}
|
|
|
|
|
+ requestAnimationFrame(() => {
|
|
|
|
|
+ try { icon.classList.add(`${PREFIX}icon-show`); } catch {}
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (!X) return;
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
// Entrance varies slightly by type (SweetAlert-like feel)
|
|
// Entrance varies slightly by type (SweetAlert-like feel)
|
|
|
if (type === 'error') {
|
|
if (type === 'error') {
|