npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@phloxcz/capify

v1.2.0

Published

Modern, themeable replacement for native alert, confirm & prompt dialogs. Zero dependencies.

Readme

Capify

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.loading(html, opts?) | { close(), update(html) } | Okénko bez tlačítek s libovolným HTML, zavírá se programově | | 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' | | html | boolean | false | true = titulek/zpráva se vloží jako raw HTML (needescapuje se) |

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.

Loading

Okénko ve stejném stylu jako alert/confirm/prompt, ale bez tlačítek — pro libovolné HTML zobrazené po dobu dlouho trvající akce. Zavírá se výhradně programově přes vrácený handle, nereaguje na klik na overlay ani Escape (pokud to explicitně nepovolíte).

const loader = Capify.loading('<div class="cap-spinner"></div><span>Ukládám…</span>');

await saveData();

loader.close();

Obsah je ve výchozím stavu vkládán jako raw HTML (html: true), protože smyslem je zobrazit vlastní markup (spinner, progress bar apod.) — pokud potřebujete escapovat, nastavte html: false. Capify.loading() respektuje theme, darkMode, modal, overlay volby i variant: 'popover' + anchor/placement stejně jako ostatní metody. Vrácený handle má i update(html) pro změnu obsahu za běhu (např. update procenta průběhu), aniž by se okno muselo zavírat a znovu otevírat.

// Popover verze u tlačítka, bez overlay
const loader = Capify.loading('Nahrávám soubor…', {
  variant: 'popover',
  anchor: uploadBtn,
  placement: 'bottom-left',
  modal: false,
});

loader.update('Nahrávám… 80 %');
loader.close();

CSS třída .cap-spinner je volitelný předpřipravený spinner v barvách aktuálního tématu (--cap-accent/--cap-border), který lze použít v obsahu, ale není povinný — klidně vložte vlastní HTML/GIF/progress bar.

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,
  html: false,                    // true = titulek/zpráva se vloží jako raw HTML (needescapuje se)
  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