You could overwrite the confirmJs form helper template to use custom JS.
For FormHelper::postLink() calls the template will, among others, receive the template variables confirmMessage, which is a JSON string with the confirm message, and formName, which is a literal string holding the form name. For FormHelper::button() calls there will be no formName, so you'd need to take that into account if you want to support that usage too!
While you could put the whole sweet alert code in the confirmJs template, I'm not sure that all browsers do finally support linebreaks in HTML attributes, so to be on the safe side you may want to use a helper function (it's also more readable).
For example:
<script>
function swalConfirm(buttonOrLink, message, formName) {
Swal.fire({
title: message,
showCancelButton: true,
confirmButtonText: `Yes`,
denyButtonText: `No`,
}).then((result) => {
if (result.isConfirmed) {
//Proceeds to submit form
if (formName) {
// it's a `postLink` form
document[formName].submit();
} else if (buttonOrLink.form) {
// it's a regular form
buttonOrLink.form.submit();
} else {
// it's something that shouldn't exist,
// possibly a form button outside a form...
}
} else if (result.isDenied) {
//Just closing the confirmation
}
});
}
</script>
<?php
$this->Form->setTemplates([
'confirmJs' => 'swalConfirm(this, {{confirmMessage}}, "{{formName}}"); event.returnValue = false; return false;',
]);
?>
Then you could simply use your postLink() call as-is:
echo $this->Form->postLink(
__('Withdraw'),
['action' => 'request'],
['confirm' => __('Are you sure?'), 'class' => 'btn btn-outline-dark mb-0 ms-auto']
);
See also
ps. Note that as of CakePHP 4, the confirmMessage template variable will not be a JSON string anymore, but an HTML entity encoded string literal, so you'd have to explicitly put it in quotes:
'swalConfirm(this, "{{confirmMessage}}", "{{formName}}")',
or use the data-confirm-message attribute that has been introduced with 4.x:
'swalConfirm(this, this.getAttribute("data-confirm-message"), "{{formName}}")',
or for modern browsers:
'swalConfirm(this, this.dataset.confirmMessage, "{{formName}}")',