phloxcz / capify
Modern, themeable replacement for native alert, confirm & prompt dialogs. Zero dependencies.
README
Modern, themeable replacement for native alert(), confirm() and prompt() dialogs.
Zero dependencies · ~5 KB · UMD · TypeScript ready
Features
- 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()
Installation
npm (recommended for Vite / bundler projects)
npm install @phloxcz/capify
import Capify from '@phloxcz/capify'; import '@phloxcz/capify/capify.css';
Composer
composer require phloxcz/capify
Soubory 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.
CDN / manuálně
<link href="capify.css" rel="stylesheet"> <script src="capify.js"></script>
Nette + Vite
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.
1. Předpoklady
composer require nette/assets npm install vite @nette/vite-plugin
2. Instalace Capify
npm install @phloxcz/capify
3. Entry point
V 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', });
4. Vite config
// vite.config.ts import { defineConfig } from 'vite'; import nette from '@nette/vite-plugin'; export default defineConfig({ plugins: [ nette({ entry: 'app.js' }), ], });
5. Nette config
# config/common.neon assets: mapping: default: type: vite
6. Latte šablona
{* @layout.latte *} <!DOCTYPE html> <html> <head> {asset 'app.js'} {* Vite vloží JS + CSS automaticky *} </head> <body> {include content} </body> </html>
7. Použití v šablonách
{* 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ývoj vs. produkce
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.
Composer bez bundleru
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.css
V Latte pak:
<link rel="stylesheet" href="{$basePath}/css/capify.css"> <script src="{$basePath}/js/capify.js"></script>
Quick Start
<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>
TypeScript
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);
API
| 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 |
Popover varianta
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', });
Placement
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ý.
Overlay
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.
Notifikace
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();
Notify options
| 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' |
Chování
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.
Per-call Options
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' });
Class Overrides
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', } });
Dostupné sloty podle tématu
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
Témata
- 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
Soubory
| 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 |
Licence
MIT