Skip to content

Instantly share code, notes, and snippets.

@genox
Created July 10, 2023 06:58
Show Gist options
  • Save genox/ed146632f1a66a4b97cd45e05cb237b9 to your computer and use it in GitHub Desktop.
Save genox/ed146632f1a66a4b97cd45e05cb237b9 to your computer and use it in GitHub Desktop.
Confirmation dialog component for Qwik, Daisy ui
import type { PropFunction, Signal } from '@builder.io/qwik';
import { $, component$, Slot, useSignal, useTask$ } from '@builder.io/qwik';
import { useTranslate } from 'qwik-speak';
type Props = {
title?: string;
confirmAction?: PropFunction<() => void>;
cancelAction?: PropFunction<() => void>;
openSignal: Signal<boolean>;
isDangerous?: boolean;
};
export const Dialog = component$<Props>(
({ title, openSignal, cancelAction, confirmAction, isDangerous = false }) => {
const modalRef = useSignal<HTMLDialogElement>();
const t = useTranslate();
useTask$(async ({ track }) => {
const state = track(() => openSignal.value);
console.log('state', state);
if (state) {
console.log('show modal');
modalRef?.value?.showModal();
}
if (!state) {
modalRef?.value?.close();
}
});
const cancelAndCloseModal$ = $(async () => {
await cancelAction?.();
openSignal.value = false;
});
const confirmAndCloseModal$ = $(async () => {
await confirmAction?.();
openSignal.value = false;
});
const confirmButtonClassIsDangerous = {
true: 'btn-warning btn-sm btn',
false: 'btn-success btn-sm btn',
};
return (
<>
<Slot name="trigger" />
<dialog class="modal" ref={modalRef}>
<div class="modal-box">
{title && <h3 class="text-lg font-bold">{title}</h3>}
<div class="py-4">
<Slot name={'content'} />
</div>
<div class="modal-action">
{confirmAction && (
<>
<button
class={confirmButtonClassIsDangerous[`${isDangerous}`]}
onClick$={confirmAndCloseModal$}>
{t('app.store.dialog.cancel@@OK')}
</button>
<button class="btn-sm btn" onClick$={cancelAndCloseModal$}>
{t('app.store.dialog.cancel@@Cancel')}
</button>
</>
)}
{!confirmAction && (
<button class="btn-sm btn" onClick$={cancelAndCloseModal$}>
{t('app.store.dialog.cancel@@Close')}
</button>
)}
</div>
</div>
</dialog>
</>
);
}
);
const Usage = component$(() => {
const dialogIsOpen = useSignal(false)
const onRemoveClick$ = $(async () => {
await action()
});
return (
<div>
<Dialog confirmAction={onRemoveClick$} openSignal={dialogIsOpen}>
<button
class={'btn-error btn-xs btn'}
onClick$={() => (dialogIsOpen.value = true)}
q:slot={'trigger'}>
Do this
</button>
<div q:slot={'content'}>
<p>
Are you sure you want to do this?
</p>
</div>
</Dialog>
</div>
);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment