Tighten payment sheet UI to match POS single-surface checkout.
Deploy Ladill Give / deploy (push) Successful in 54s
Deploy Ladill Give / deploy (push) Successful in 54s
When Paystack Inline is ready: widen desktop panel for channel sidebar, collapse to a minimal header, hide footer trust line, and re-pin the checkout iframe to the sheet body so it does not read as a second modal on top of Ladill chrome.
This commit is contained in:
@@ -312,6 +312,19 @@
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function syncPaystackMountBox() {
|
||||
try {
|
||||
var mount = getPaystackMount();
|
||||
if (!mount || !window.__ladillContainPaystack) return;
|
||||
var rect = mount.getBoundingClientRect();
|
||||
var root = document.documentElement;
|
||||
root.style.setProperty('--ladill-pay-left', Math.max(0, Math.round(rect.left)) + 'px');
|
||||
root.style.setProperty('--ladill-pay-top', Math.max(0, Math.round(rect.top)) + 'px');
|
||||
root.style.setProperty('--ladill-pay-width', Math.max(0, Math.round(rect.width)) + 'px');
|
||||
root.style.setProperty('--ladill-pay-height', Math.max(0, Math.round(rect.height)) + 'px');
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function setPaystackContainActive(active) {
|
||||
window.__ladillContainPaystack = !!active;
|
||||
try {
|
||||
@@ -321,6 +334,20 @@
|
||||
installIframeAllowHook();
|
||||
installAppendHook();
|
||||
ensurePaystackContained(document);
|
||||
syncPaystackMountBox();
|
||||
if (!window.__ladillPayMountResizeBound) {
|
||||
window.__ladillPayMountResizeBound = true;
|
||||
window.addEventListener('resize', syncPaystackMountBox, { passive: true });
|
||||
window.addEventListener('orientationchange', syncPaystackMountBox, { passive: true });
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
var root = document.documentElement;
|
||||
root.style.removeProperty('--ladill-pay-left');
|
||||
root.style.removeProperty('--ladill-pay-top');
|
||||
root.style.removeProperty('--ladill-pay-width');
|
||||
root.style.removeProperty('--ladill-pay-height');
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,6 +577,13 @@
|
||||
store.launching = false;
|
||||
ensurePaystackIframePermissions(document);
|
||||
ensurePaystackContained(document);
|
||||
// After Alpine hides the loading overlay, re-measure mount and re-pin iframe.
|
||||
setTimeout(function () {
|
||||
ensurePaystackContained(document);
|
||||
syncPaystackMountBox();
|
||||
}, 0);
|
||||
setTimeout(syncPaystackMountBox, 120);
|
||||
setTimeout(syncPaystackMountBox, 400);
|
||||
},
|
||||
onSuccess: function (transaction) {
|
||||
if (token !== store._launchToken) return;
|
||||
@@ -647,6 +681,7 @@
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
}
|
||||
/* Paystack draws its own modal chrome inside the iframe — give it the full body. */
|
||||
[data-ladill-pay-mount] iframe[data-ladill-pay-contained],
|
||||
[data-ladill-pay-mount] iframe[id^="inline-checkout"],
|
||||
[data-ladill-pay-mount] iframe[id^="embed-checkout"] {
|
||||
@@ -662,10 +697,31 @@
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
z-index: 2 !important;
|
||||
visibility: visible !important;
|
||||
display: block !important;
|
||||
background: transparent !important;
|
||||
background: #fff !important;
|
||||
color-scheme: light !important;
|
||||
}
|
||||
/* If a Paystack frame escapes the mount, pin it over the panel body instead of full viewport. */
|
||||
html.ladill-pay-inline-active body > iframe[id^="inline-checkout"],
|
||||
html.ladill-pay-inline-active body > iframe[id^="embed-checkout"] {
|
||||
position: fixed !important;
|
||||
/* Fallback rect; JS updates these CSS vars from the mount box. */
|
||||
left: var(--ladill-pay-left, 0) !important;
|
||||
top: var(--ladill-pay-top, 0) !important;
|
||||
width: var(--ladill-pay-width, 100%) !important;
|
||||
height: var(--ladill-pay-height, 100%) !important;
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
margin: 0 !important;
|
||||
border: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
z-index: 10000 !important;
|
||||
visibility: visible !important;
|
||||
display: block !important;
|
||||
background: #fff !important;
|
||||
}
|
||||
</style>
|
||||
@endonce
|
||||
@@ -714,10 +770,18 @@
|
||||
@click="showSheet = false; window.LadillPayCheckout?.cancel?.()">
|
||||
</div>
|
||||
|
||||
{{-- Always wrap payment: bottom sheet on mobile, centered modal on desktop. --}}
|
||||
{{--
|
||||
Single payment surface (same pattern as POS):
|
||||
- Mobile: bottom sheet
|
||||
- Desktop: centered modal, wide enough for Paystack channel sidebar
|
||||
- When Inline is ready: minimal chrome so Paystack fills the body (no double header/footer)
|
||||
--}}
|
||||
<div data-ladill-pay-panel
|
||||
class="relative flex w-full flex-col overflow-hidden rounded-t-2xl bg-white shadow-2xl md:max-w-lg md:rounded-2xl"
|
||||
style="height: min(90dvh, 720px); max-height: 90dvh; padding-bottom: env(safe-area-inset-bottom, 0px)"
|
||||
class="relative flex w-full flex-col overflow-hidden rounded-t-2xl bg-white shadow-2xl md:rounded-2xl"
|
||||
:class="($store.ladillPayCheckout && $store.ladillPayCheckout.inline && !$store.ladillPayCheckout.launching && !$store.ladillPayCheckout.error)
|
||||
? 'md:max-w-3xl'
|
||||
: 'md:max-w-lg'"
|
||||
style="height: min(92dvh, 760px); max-height: 92dvh; padding-bottom: env(safe-area-inset-bottom, 0px)"
|
||||
x-show="showSheet"
|
||||
x-transition:enter="transition duration-300 ease-out md:duration-200"
|
||||
x-transition:enter-start="translate-y-full opacity-0 md:translate-y-0 md:scale-95"
|
||||
@@ -726,8 +790,16 @@
|
||||
x-transition:leave-start="translate-y-0 opacity-100 md:scale-100"
|
||||
x-transition:leave-end="translate-y-full opacity-0 md:translate-y-0 md:scale-95"
|
||||
@click.stop>
|
||||
<div class="relative flex shrink-0 flex-col gap-0.5 border-b border-slate-100 px-4 pb-3 pt-5 md:px-5 md:pt-3"
|
||||
style="padding-top: max(1.25rem, env(safe-area-inset-top, 0px))">
|
||||
|
||||
{{-- Full title header only while loading / error / same-origin frame --}}
|
||||
<div x-show="!$store.ladillPayCheckout
|
||||
|| $store.ladillPayCheckout.frameable
|
||||
|| $store.ladillPayCheckout.launching
|
||||
|| $store.ladillPayCheckout.error
|
||||
|| !$store.ladillPayCheckout.inline"
|
||||
class="relative flex shrink-0 flex-col gap-0.5 border-b border-slate-100 px-4 pb-3 pt-5 md:px-5 md:pt-3"
|
||||
style="padding-top: max(1.25rem, env(safe-area-inset-top, 0px))"
|
||||
data-ladill-pay-header>
|
||||
<div class="absolute left-1/2 top-2 h-1 w-10 -translate-x-1/2 rounded-full bg-slate-200 md:hidden" data-ladill-pay-handle aria-hidden="true"></div>
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div class="min-w-0">
|
||||
@@ -748,10 +820,32 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Body: Paystack mounts here (same area as the spinner). No second full-screen modal. --}}
|
||||
<div class="relative min-h-0 flex-1 overflow-hidden overscroll-contain"
|
||||
|
||||
{{-- Minimal chrome once Paystack owns the body (one close, no second title stack) --}}
|
||||
<div x-show="$store.ladillPayCheckout
|
||||
&& $store.ladillPayCheckout.inline
|
||||
&& !$store.ladillPayCheckout.launching
|
||||
&& !$store.ladillPayCheckout.error
|
||||
&& !$store.ladillPayCheckout.frameable"
|
||||
class="relative z-20 flex shrink-0 items-center justify-between px-3 pb-1 pt-3 md:px-4 md:pt-2"
|
||||
style="padding-top: max(0.75rem, env(safe-area-inset-top, 0px))"
|
||||
data-ladill-pay-header-minimal>
|
||||
<div class="absolute left-1/2 top-2 h-1 w-10 -translate-x-1/2 rounded-full bg-slate-200 md:hidden" data-ladill-pay-handle aria-hidden="true"></div>
|
||||
<p class="pl-1 text-xs font-medium text-slate-500">{{ $sheetTitle }}</p>
|
||||
<button type="button"
|
||||
@click="showSheet = false; window.LadillPayCheckout?.cancel?.()"
|
||||
class="shrink-0 rounded-full p-1.5 text-slate-400 transition hover:bg-slate-100 hover:text-slate-700"
|
||||
aria-label="Close">
|
||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{{-- Body: Paystack mounts here (same area as the spinner). --}}
|
||||
<div class="relative min-h-0 flex-1 overflow-hidden overscroll-contain bg-white"
|
||||
data-ladill-pay-body
|
||||
style="min-height: 28rem">
|
||||
style="min-height: 22rem">
|
||||
{{-- Same-origin waiting pages (e.g. MoMo status) --}}
|
||||
<iframe x-show="$store.ladillPayCheckout && $store.ladillPayCheckout.frameable"
|
||||
:src="showSheet && $store.ladillPayCheckout && $store.ladillPayCheckout.frameable ? checkoutUrl : ''"
|
||||
@@ -814,8 +908,16 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Footer only before Paystack owns the body (avoids double trust messaging) --}}
|
||||
@if (! empty($sheetFooter))
|
||||
<p class="shrink-0 border-t border-slate-100 bg-slate-50 px-4 py-2 text-center text-[11px] text-slate-500 md:px-5">
|
||||
<p x-show="!$store.ladillPayCheckout
|
||||
|| $store.ladillPayCheckout.frameable
|
||||
|| $store.ladillPayCheckout.launching
|
||||
|| $store.ladillPayCheckout.error
|
||||
|| !$store.ladillPayCheckout.inline"
|
||||
class="shrink-0 border-t border-slate-100 bg-slate-50 px-4 py-2 text-center text-[11px] text-slate-500 md:px-5"
|
||||
data-ladill-pay-footer>
|
||||
{{ $sheetFooter }}
|
||||
</p>
|
||||
@endif
|
||||
|
||||
Reference in New Issue
Block a user