Modern, themeable replacement for native alert(), confirm() and prompt() dialogs.
Zero dependencies · ~5 KB · UMD · TypeScript ready
- Three built-in themes: Default (custom), Bootstrap 5, Tailwind CSS
- Dark / Light mode: auto-detect via
prefers-color-scheme, or force light/dark - Modal & non-modal: modal variant includes backdrop blur effect
- Promise-based API:
await Capify.confirm('Sure?') - Popover variant: kompaktní dialog ukotvený k elementu s auto-flip
- Notifications: toast notifikace se štosováním, auto-dismiss, progress bar
- Class overrides: customize any CSS class slot globally or per-call
- Accessible:
role="dialog",aria-modal, keyboard support (Escape, Enter) - Extensible: register custom themes via
Capify.registerTheme()
npm install @phloxcz/capifyimport Capify from '@phloxcz/capify';
import '@phloxcz/capify/capify.css';composer require phloxcz/capifySoubory se nainstalují do vendor/phloxcz/capify/. Jak je dostat do
veřejné složky závisí na tvém setupu — viz sekce Nette + Vite
a Composer bez bundleru níže.
<link href="capify.css" rel="stylesheet">
<script src="capify.js"></script>Doporučený moderní setup — Capify se nainstaluje přes npm, Vite ho
zabundlí spolu se zbytkem frontendu a nette/assets se postará o
vložení do šablon.
composer require nette/assets
npm install vite @nette/vite-pluginnpm install @phloxcz/capifyV hlavním JS souboru (typicky assets/app.js nebo assets/main.js)
importuj Capify:
// assets/app.js
import '@phloxcz/capify/capify.css'; // CSS se zabundlí automaticky
import Capify from '@phloxcz/capify';
// Zpřístupni globálně (pro použití v inline scriptech a Latte šablonách)
window.Capify = Capify;
// Volitelně — globální konfigurace
Capify.config({
theme: 'bootstrap',
darkMode: 'auto',
okText: 'OK',
cancelText: 'Zrušit',
});// vite.config.ts
import { defineConfig } from 'vite';
import nette from '@nette/vite-plugin';
export default defineConfig({
plugins: [
nette({ entry: 'app.js' }),
],
});# config/common.neon
assets:
mapping:
default:
type: vite{* @layout.latte *}
<!DOCTYPE html>
<html>
<head>
{asset 'app.js'} {* Vite vloží JS + CSS automaticky *}
</head>
<body>
{include content}
</body>
</html>{* kdekoliv v šabloně — Capify je na window *}
<button onclick="Capify.confirm('Opravdu smazat?').then(ok => { if (ok) location.href = '{link delete! $id}' })">
Smazat
</button>Nebo v samostatném JS modulu:
// assets/modules/admin.js
import Capify from '@phloxcz/capify';
document.querySelectorAll('[data-confirm]').forEach(el => {
el.addEventListener('click', async (e) => {
e.preventDefault();
const ok = await Capify.confirm(el.dataset.confirm, { title: 'Potvrdit akci' });
if (ok) location.href = el.href;
});
});V dev módu (npx vite) se Capify načítá přes Vite dev server s HMR —
změny v CSS se projeví okamžitě bez reloadu. Pro produkci spustíš
npx vite build, Vite vygeneruje optimalizované soubory do www/assets/
a nette/assets je automaticky servíruje se správným verzováním.
Pokud nepoužíváš Vite ani jiný bundler, můžeš soubory z vendor/
nakopírovat do veřejné složky ručně nebo symlinkem:
# Symlink (Linux/macOS)
ln -s ../../vendor/phloxcz/capify/capify.js www/js/capify.js
ln -s ../../vendor/phloxcz/capify/capify.css www/css/capify.cssV Latte pak:
<link rel="stylesheet" href="{$basePath}/css/capify.css">
<script src="{$basePath}/js/capify.js"></script><link href="capify.css" rel="stylesheet">
<script src="capify.js"></script>
<script>
Capify.config({
theme: 'default', // 'default' | 'bootstrap' | 'tailwind'
modal: true, // true = blur overlay
darkMode: 'auto', // 'auto' | 'light' | 'dark'
});
await Capify.alert('Hotovo!');
const ok = await Capify.confirm('Smazat?');
const name = await Capify.prompt('Vaše jméno?');
</script>Typové definice jsou součástí balíčku (capify.d.ts):
import Capify from '@phloxcz/capify';
import type { DialogOptions, CapifyConfig, ThemeRenderer } from '@phloxcz/capify';
const opts: DialogOptions = {
title: 'Potvrdit',
theme: 'bootstrap',
classes: {
header: 'modal-header border-0',
btnOk: 'btn btn-danger',
},
};
const confirmed: boolean = await Capify.confirm('Smazat?', opts);| Metoda | Vrací | Popis |
|---|---|---|
Capify.alert(msg, opts?) |
Promise<true> |
Notifikace s tlačítkem OK |
Capify.confirm(msg, opts?) |
Promise<boolean> |
OK → true, Cancel → false |
Capify.prompt(msg, opts?) |
Promise<string|null> |
OK → zadaný text, Cancel → null |
Capify.notify(msg, opts?) |
{ close() } |
Toast notifikace, vrací handle |
Capify.config(opts) |
void |
Nastaví globální výchozí hodnoty |
Capify.registerTheme(name, renderer) |
void |
Registrace vlastního tématu |
Capify.getThemeClasses(name) |
object|null |
Vrátí výchozí třídy tématu |
Capify.reset() |
void |
Reset konfigurace na výchozí hodnoty |
Kompaktní dialog ukotvený k libovolnému elementu — ideální pro kontextové vstupy, inline potvrzení nebo notifikace přímo u tlačítka.
// Prompt popover pod tlačítkem, zarovnaný vlevo
const name = await Capify.prompt('Název:', {
variant: 'popover',
anchor: document.getElementById('myBtn'),
placement: 'bottom-left',
modal: true, // volitelný blur overlay
okText: 'Uložit',
cancelText: 'Zrušit',
});
// Confirm popover bez overlay
const ok = await Capify.confirm('Smazat?', {
variant: 'popover',
anchor: deleteBtn,
placement: 'bottom-right',
modal: false,
});
// Alert popover
await Capify.alert('Uloženo.', {
variant: 'popover',
anchor: saveBtn,
placement: 'top-left',
});Kombinace vertikální a horizontální osy:
| Hodnota | Dialog se objeví… |
|---|---|
bottom-left |
Pod elementem, zarovnaný k levému okraji |
bottom-right |
Pod elementem, zarovnaný k pravému okraji |
top-left |
Nad elementem, zarovnaný k levému okraji |
top-right |
Nad elementem, zarovnaný k pravému okraji |
Automatický flip — pokud se dialog nevejde na zadanou stranu, otočí se na opačnou. Na mobilech (< 480px) se popover zobrazí vycentrovaný.
Vzhled modálního overlay (pozadí za dialogem) je plně konfigurovatelný.
// Silnější blur
Capify.config({ overlayBlur: 12 });
// Bez bluru
Capify.config({ overlayBlur: 0 });
// Tmavší overlay
Capify.config({ overlayBg: 'rgba(0, 0, 0, .7)' });
// Světlý frost efekt
Capify.config({
overlayBlur: 8,
overlayBg: 'rgba(255, 255, 255, .3)',
});
// Plně vlastní backdrop-filter (přebije overlayBlur)
Capify.alert('OK', {
overlayFilter: 'blur(4px) brightness(.7) saturate(.5)',
});| Volba | Typ | Default | Popis |
|---|---|---|---|
overlayBlur |
number |
6 |
Blur v px, 0 = bez bluru |
overlayBg |
string |
rgba(0,0,0,.45) |
Barva pozadí overlay |
overlayFilter |
string |
— | Vlastní backdrop-filter (přebije overlayBlur) |
Všechny tři lze nastavit globálně i per-call.
Toast notifikace, které se štosují na zvolené pozici. Auto-dismiss s progress barem, pause na hover, programatické zavření.
// Základní použití
Capify.notify('Soubor uložen.', {
type: 'success', // 'info' | 'success' | 'warning' | 'error'
title: 'Hotovo', // volitelný titulek
position: 'top-right', // kam na obrazovku
duration: 4000, // ms, 0 = bez auto-dismiss
});
// Všechny pozice
// 'top-left' | 'top-center' | 'top-right'
// 'bottom-left' | 'bottom-center' | 'bottom-right'
// Persistent notifikace s programatickým zavřením
const n = Capify.notify('Zpracovávám...', {
type: 'info',
duration: 0, // nezavře se samo
});
// ... později:
n.close();| Volba | Typ | Default | Popis |
|---|---|---|---|
position |
string |
'top-right' |
Pozice na obrazovce (6 možností) |
duration |
number |
4000 |
Auto-dismiss v ms, 0 = manuální |
type |
string |
'info' |
Typ — ovlivňuje barvu akcentu |
title |
string |
'' |
Tučný titulek nad zprávou |
closable |
boolean |
true |
Zobrazit tlačítko × |
maxWidth |
number |
380 |
Maximální šířka v px |
showProgress |
boolean |
true |
Progress bar odpočtu |
theme |
string |
z config | 'default' / 'bootstrap' / 'tailwind' |
darkMode |
string |
z config | 'auto' / 'light' / 'dark' |
Notifikace se štosují automaticky — top pozice rostou dolů, bottom pozice rostou nahoru. Při najetí myší se odpočet pozastaví a progress bar se zastaví. Po odjetí myši odpočet pokračuje.
Notifikace respektují globální téma (default, bootstrap, tailwind)
a dark mode. Bootstrap používá alert komponenty, Tailwind utility třídy
s barevnými variantami per type. Přetížení tříd funguje přes classes
stejně jako u dialogů — notify sloty: notifyCard, notifyTitle,
notifyMsg, notifyClose, notifyProgress.
Capify.confirm('Uložit?', {
title: 'Neuložené změny',
okText: 'Uložit',
cancelText: 'Zahodit',
theme: 'bootstrap',
modal: true,
darkMode: 'dark',
closeOnOverlay: true,
closeOnEscape: true,
zIndex: 10000,
animationDuration: 200,
classes: { ... },
// overlay appearance
overlayBlur: 6, // blur in px (0 = off)
overlayBg: 'rgba(0,0,0,.45)', // overlay background color
overlayFilter: null, // custom backdrop-filter (overrides overlayBlur)
// popover options
variant: 'popover', // 'dialog' (default) | 'popover'
anchor: HTMLElement, // element pro ukotvení
placement: 'bottom-left', // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
});Každé téma definuje pojmenované sloty s výchozími CSS třídami. Jakýkoli
slot lze přetížit globálně přes config() nebo jednorázově přes options.classes.
// Zjisti dostupné sloty:
console.log(Capify.getThemeClasses('bootstrap'));
// → { content: 'modal-content shadow-lg border-0 text-body bg-body',
// header: 'modal-header border-bottom',
// footer: 'modal-footer border-top',
// btnOk: 'btn btn-primary', ... }
// Přetížení globálně:
Capify.config({
theme: 'bootstrap',
classes: {
header: 'modal-header border-0',
footer: 'modal-footer border-0',
}
});
// Přetížení per-call:
Capify.confirm('Smazat vše?', {
classes: {
btnOk: 'btn btn-danger',
header: 'modal-header border-0 bg-danger bg-opacity-10',
}
});Default (dialog): overlay, dialog, title, body, input, actions, btnOk, btnCancel
Default (notify): notifyCard, notifyTitle, notifyMsg, notifyClose, notifyProgress
Bootstrap (dialog): overlay, dialog, content, header, title, body, bodyText, input, footer, btnOk, btnCancel
Bootstrap (notify): notifyCard, notifyCardInfo, notifyCardSuccess, notifyCardWarning, notifyCardError, notifyTitle, notifyMsg, notifyClose, notifyProgress
Tailwind (dialog): overlay, dialog, card, cardLight, cardDark, title, body, input, inputLight, inputDark, actions, btnOk, btnCancel, btnCancelLight, btnCancelDark
Tailwind (notify): notifyCard, notifyCardLightInfo, notifyCardLightSuccess, notifyCardLightWarning, notifyCardLightError, notifyCardDarkInfo, notifyCardDarkSuccess, notifyCardDarkWarning, notifyCardDarkError, notifyTitle, notifyMsg, notifyClose, notifyProgress
- Default — plně samostatné, potřebuje jen
capify.css - Bootstrap — využívá třídy Bootstrap 5, vyžaduje Bootstrap CSS
- Tailwind — využívá Tailwind utility třídy, vyžaduje Tailwind CSS
| Soubor | Účel |
|---|---|
capify.js |
Knihovna (UMD) |
capify.css |
Styly — bundluj se styly projektu |
capify.d.ts |
TypeScript definice |
package.json |
npm manifest |
composer.json |
Composer manifest |
demo.html |
Interaktivní demo |
MIT