fix(banner): create better banner style

This commit is contained in:
2026-05-08 18:43:06 +03:30
parent ea68db6c01
commit 8345e94a1b
3 changed files with 214 additions and 105 deletions

View File

@@ -1,112 +1,178 @@
.sodino-banner { .sodino-banner-wrap {
direction: rtl; direction: rtl;
position: relative; position: relative;
z-index: 9999; z-index: 99990;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; box-sizing: border-box;
} margin: 18px auto;
width: min(1120px, calc(100% - 32px));
.sodino-banner-wrap { padding: 18px;
margin: 0 auto; overflow: hidden;
max-width: 1200px; color: #172033;
padding: 18px 22px;
background: #ffffff; background: #ffffff;
border: 1px solid rgba(148, 163, 184, 0.35); border: 1px solid rgba(15, 23, 42, 0.12);
border-radius: 1rem; border-radius: 18px;
box-shadow: 0 18px 35px rgba(15, 23, 42, 0.08); box-shadow: 0 18px 45px rgba(15, 23, 42, 0.14);
font-family: inherit;
} }
.sodino-banner-top { .sodino-banner-wrap *,
.sodino-banner-wrap *::before,
.sodino-banner-wrap *::after {
box-sizing: border-box;
}
.sodino-banner-content {
display: flex;
align-items: center;
justify-content: center;
min-height: 64px;
}
.sodino-banner-link {
display: block;
width: 100%;
color: inherit;
text-decoration: none;
cursor: pointer;
}
.sodino-banner-link:hover,
.sodino-banner-link:focus {
color: inherit;
text-decoration: none;
}
.sodino-banner-link:focus-visible {
outline: 3px solid rgba(37, 99, 235, 0.35);
outline-offset: 4px;
border-radius: 14px;
}
.sodino-banner-image {
display: block;
width: 100%;
height: auto;
max-height: min(420px, 70vh);
object-fit: cover;
border-radius: 14px;
}
.sodino-banner-close {
position: absolute;
top: 12px;
left: 12px;
z-index: 3;
display: inline-flex;
align-items: center;
justify-content: center;
width: 38px;
height: 38px;
padding: 0;
color: #0f172a;
background: rgba(255, 255, 255, 0.94);
border: 1px solid rgba(15, 23, 42, 0.14);
border-radius: 999px;
box-shadow: 0 10px 24px rgba(15, 23, 42, 0.18);
font-size: 26px;
line-height: 1;
cursor: pointer;
transition: background-color 160ms ease, border-color 160ms ease, transform 160ms ease;
}
.sodino-banner-close:hover,
.sodino-banner-close:focus {
background: #ffffff;
border-color: rgba(15, 23, 42, 0.28);
transform: translateY(-1px);
}
.sodino-banner-close:focus-visible {
outline: 3px solid rgba(37, 99, 235, 0.35);
outline-offset: 2px;
}
.sodino-banner-backdrop {
position: fixed; position: fixed;
top: 20px; inset: 0;
left: 50%; z-index: 99989;
transform: translateX(-50%); background: rgba(15, 23, 42, 0.46);
width: calc(100% - 32px); backdrop-filter: blur(3px);
max-width: 1100px;
}
.sodino-banner-bottom {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
width: calc(100% - 32px);
max-width: 1100px;
}
.sodino-banner-floating_bar {
position: fixed;
left: 50%;
transform: translateX(-50%);
width: calc(100% - 32px);
max-width: 1100px;
}
.sodino-banner-position-top.sodino-banner-floating_bar,
.sodino-banner-position-middle.sodino-banner-floating_bar {
top: 20px;
}
.sodino-banner-position-bottom.sodino-banner-floating_bar,
.sodino-banner-position-cart.sodino-banner-floating_bar,
.sodino-banner-position-product_page.sodino-banner-floating_bar {
bottom: 20px;
} }
.sodino-banner-popup { .sodino-banner-popup {
position: fixed; position: fixed;
top: 50%; top: 50%;
left: 50%; left: 50%;
width: min(680px, calc(100% - 32px));
max-height: calc(100vh - 32px);
margin: 0;
padding: 46px 18px 18px;
overflow: auto;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
max-width: 95%; border-radius: 24px;
width: 680px; box-shadow: 0 28px 90px rgba(15, 23, 42, 0.28);
background: #ffffff;
box-shadow: 0 30px 60px rgba(15, 23, 42, 0.12);
} }
.sodino-banner-close { .sodino-banner-popup .sodino-banner-content {
position: absolute; min-height: 120px;
top: 14px;
right: 16px;
background: rgba(15, 23, 42, 0.06);
border: none;
color: #0f172a;
width: 36px;
height: 36px;
border-radius: 9999px;
font-size: 1.2rem;
cursor: pointer;
} }
.sodino-banner-content { .sodino-banner-popup .sodino-banner-image {
display: flex; max-height: min(560px, 72vh);
justify-content: center; border-radius: 18px;
align-items: center;
gap: 20px;
flex-wrap: wrap;
} }
.sodino-banner-image { .sodino-banner-floating_bar,
width: 100%; .sodino-banner-position-top.sodino-banner-inline,
height: auto; .sodino-banner-position-bottom.sodino-banner-inline {
border-radius: 1rem; position: fixed;
display: block; left: 50%;
width: min(1040px, calc(100% - 32px));
margin: 0;
transform: translateX(-50%);
} }
.sodino-banner-link { .sodino-banner-position-top.sodino-banner-floating_bar,
display: inline-block; .sodino-banner-position-top.sodino-banner-inline {
top: 18px;
}
.sodino-banner-position-bottom.sodino-banner-floating_bar,
.sodino-banner-position-bottom.sodino-banner-inline,
.sodino-banner-position-cart.sodino-banner-floating_bar,
.sodino-banner-position-product_page.sodino-banner-floating_bar {
bottom: 18px;
}
.sodino-banner-position-middle.sodino-banner-floating_bar {
top: 18px;
} }
@media (max-width: 768px) { @media (max-width: 768px) {
.sodino-banner-top, .sodino-banner-wrap {
.sodino-banner-bottom,
.sodino-banner-floating_bar,
.sodino-banner-popup {
width: calc(100% - 20px); width: calc(100% - 20px);
left: 50%; padding: 14px;
transform: translateX(-50%); border-radius: 16px;
} }
.sodino-banner-popup { .sodino-banner-popup {
max-width: 95%; width: calc(100% - 20px);
padding: 44px 12px 12px;
border-radius: 20px;
transform: translate(-50%, -50%);
}
.sodino-banner-floating_bar,
.sodino-banner-position-top.sodino-banner-inline,
.sodino-banner-position-bottom.sodino-banner-inline {
width: calc(100% - 20px);
}
.sodino-banner-close {
top: 9px;
left: 9px;
width: 34px;
height: 34px;
font-size: 24px;
} }
} }

View File

@@ -44,10 +44,11 @@ function sodino_get_banner_html($banner) {
switch ($banner->content_type) { switch ($banner->content_type) {
case 'image': case 'image':
$image = esc_url($banner->content_value); $image = esc_url($banner->content_value);
$image_html = '<img src="' . $image . '" alt="' . esc_attr($banner->title) . '" class="sodino-banner-image" />';
if (!empty($banner->link_url)) { if (!empty($banner->link_url)) {
$content = sprintf('<a href="%s" class="sodino-banner-link" data-banner-id="%d">%s</a>', esc_url($banner->link_url), esc_attr($banner->id), '<img src="' . $image . '" alt="' . esc_attr($banner->title) . '" class="sodino-banner-image" />'); $content = sprintf('<a href="%s" class="sodino-banner-link" data-banner-id="%d">%s</a>', esc_url($banner->link_url), esc_attr($banner->id), $image_html);
} else { } else {
$content = '<img src="' . $image . '" alt="' . esc_attr($banner->title) . '" class="sodino-banner-image" />'; $content = $image_html;
} }
break; break;
case 'shortcode': case 'shortcode':
@@ -64,14 +65,15 @@ function sodino_get_banner_html($banner) {
$linkAttributes = sprintf(' data-banner-id="%d" href="%s" class="sodino-banner-link"', esc_attr($banner->id), esc_url($banner->link_url)); $linkAttributes = sprintf(' data-banner-id="%d" href="%s" class="sodino-banner-link"', esc_attr($banner->id), esc_url($banner->link_url));
} }
$closeButton = '<button type="button" class="sodino-banner-close" aria-label="'.esc_attr__('بستن بنر', 'sodino').'">&times;</button>'; $closeButton = '<button type="button" class="sodino-banner-close" aria-label="'.esc_attr__('بستن بنر', 'sodino').'" title="'.esc_attr__('بستن بنر', 'sodino').'">&times;</button>';
$wrapperClass = 'sodino-banner-wrap sodino-banner-' . esc_attr($banner->display_type) . ' sodino-banner-position-' . esc_attr($banner->position); $wrapperClass = 'sodino-banner-wrap sodino-banner-' . esc_attr($banner->display_type) . ' sodino-banner-position-' . esc_attr($banner->position);
$style = $banner->display_type === 'popup' ? 'style="display:none;"' : ''; $style = $banner->display_type === 'popup' ? 'style="display:none;"' : '';
$html .= '<div class="' . $wrapperClass . '" data-banner-id="' . esc_attr($banner->id) . '" ' . $style . '>'; if ($banner->display_type === 'popup') {
if ($banner->display_type === 'popup' || $banner->display_type === 'floating_bar') { $html .= '<div class="sodino-banner-backdrop" data-banner-backdrop="' . esc_attr($banner->id) . '" style="display:none;"></div>';
$html .= $closeButton;
} }
$html .= '<div class="' . $wrapperClass . '" data-banner-id="' . esc_attr($banner->id) . '" role="region" aria-label="' . esc_attr($banner->title) . '" ' . $style . '>';
$html .= $closeButton;
$html .= '<div class="sodino-banner-content">'; $html .= '<div class="sodino-banner-content">';
if ($banner->content_type !== 'image' && !empty($banner->link_url)) { if ($banner->content_type !== 'image' && !empty($banner->link_url)) {
$html .= '<a' . $linkAttributes . '>' . $content . '</a>'; $html .= '<a' . $linkAttributes . '>' . $content . '</a>';

View File

@@ -1,5 +1,4 @@
(function () { (function () {
const closeButtons = document.querySelectorAll('.sodino-banner-close');
const clicked = new Set(); const clicked = new Set();
function getCookie(name) { function getCookie(name) {
@@ -11,6 +10,24 @@
return null; return null;
} }
function hideBanner(banner) {
if (!banner) {
return;
}
banner.style.display = 'none';
banner.setAttribute('aria-hidden', 'true');
const bannerId = banner.dataset.bannerId;
if (bannerId) {
const backdrop = document.querySelector('.sodino-banner-backdrop[data-banner-backdrop="' + bannerId + '"]');
if (backdrop) {
backdrop.style.display = 'none';
}
document.cookie = 'sodino_banner_' + bannerId + '=hidden; path=/; max-age=' + 60 * 60 * 24;
}
}
function sendClick(bannerId) { function sendClick(bannerId) {
if (!bannerId || clicked.has(bannerId) || !window.sodinoBannerFrontend) { if (!bannerId || clicked.has(bannerId) || !window.sodinoBannerFrontend) {
return; return;
@@ -21,45 +38,69 @@
fetch(window.sodinoBannerFrontend.ajaxUrl, { fetch(window.sodinoBannerFrontend.ajaxUrl, {
method: 'POST', method: 'POST',
credentials: 'same-origin', credentials: 'same-origin',
keepalive: true,
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }, headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
body: 'action=sodino_banner_click&banner_id=' + encodeURIComponent(bannerId) + '&nonce=' + encodeURIComponent(window.sodinoBannerFrontend.nonce), body: 'action=sodino_banner_click&banner_id=' + encodeURIComponent(bannerId) + '&nonce=' + encodeURIComponent(window.sodinoBannerFrontend.nonce),
}); }).catch(function () {});
} }
document.addEventListener('click', function (event) { document.addEventListener('click', function (event) {
const closeButton = event.target.closest('.sodino-banner-close');
if (closeButton) {
event.preventDefault();
event.stopPropagation();
hideBanner(closeButton.closest('.sodino-banner-wrap'));
return;
}
const backdrop = event.target.closest('.sodino-banner-backdrop');
if (backdrop) {
event.preventDefault();
const banner = document.querySelector('.sodino-banner-wrap[data-banner-id="' + backdrop.dataset.bannerBackdrop + '"]');
hideBanner(banner);
return;
}
const target = event.target.closest('.sodino-banner-link'); const target = event.target.closest('.sodino-banner-link');
if (target) { if (target) {
const bannerId = target.dataset.bannerId; sendClick(target.dataset.bannerId);
sendClick(bannerId);
} }
}); });
closeButtons.forEach(function (button) { document.addEventListener('keydown', function (event) {
button.addEventListener('click', function () { if (event.key !== 'Escape') {
const wrapper = this.closest('.sodino-banner-wrap'); return;
if (!wrapper) { }
return;
} const popup = document.querySelector('.sodino-banner-popup:not([aria-hidden="true"])');
wrapper.style.display = 'none'; if (popup) {
const bannerId = wrapper.dataset.bannerId; hideBanner(popup);
if (bannerId) { }
document.cookie = 'sodino_banner_' + bannerId + '=hidden; path=/; max-age=' + 60 * 60 * 24;
}
});
}); });
document.querySelectorAll('.sodino-banner-wrap').forEach(function (banner) { document.querySelectorAll('.sodino-banner-wrap').forEach(function (banner) {
const bannerId = banner.dataset.bannerId; const bannerId = banner.dataset.bannerId;
if (getCookie('sodino_banner_' + bannerId) === 'hidden') { if (getCookie('sodino_banner_' + bannerId) === 'hidden') {
banner.style.display = 'none'; banner.style.display = 'none';
banner.setAttribute('aria-hidden', 'true');
const backdrop = document.querySelector('.sodino-banner-backdrop[data-banner-backdrop="' + bannerId + '"]');
if (backdrop) {
backdrop.style.display = 'none';
}
return;
} }
if (banner.classList.contains('sodino-banner-popup')) { if (banner.classList.contains('sodino-banner-popup')) {
setTimeout(function () { setTimeout(function () {
if (getCookie('sodino_banner_' + bannerId) !== 'hidden') { if (getCookie('sodino_banner_' + bannerId) !== 'hidden') {
const backdrop = document.querySelector('.sodino-banner-backdrop[data-banner-backdrop="' + bannerId + '"]');
if (backdrop) {
backdrop.style.display = 'block';
}
banner.style.display = 'block'; banner.style.display = 'block';
banner.setAttribute('aria-hidden', 'false');
} }
}, 2000); }, 900);
} }
}); });
})(); })();