🚀 Szybki start
</> pokazujący kod użycia. Kliknij aby zobaczyć implementację!
Podstawowa instalacja
Dodaj do HTML:
<link rel="stylesheet" href="paper.css" />
Framework automatycznie zastosuje style papierowe do wszystkich elementów.
<!DOCTYPE html>
<html lang="pl" data-theme="light">
<head>
<link rel="stylesheet" href="paper.css" />
</head>
<body>
<div class="container">
<div class="card">Twoja treść</div>
</div>
</body>
</html>
📝 Typografia i podstawy
Skala nagłówków
H1 Tytuł główny
H2 Sekcja
H3 Podsekcja
H4 Mniejszy nagłówek
H5 Lead text
H6 Meta informacje
<h1>H1 Tytuł główny</h1>
<h2>H2 Sekcja</h2>
<h3>H3 Podsekcja</h3>
<h4>H4 Mniejszy nagłówek</h4>
<h5>H5 Lead text</h5>
<h6>H6 Meta informacje</h6>
Paragrafy i elementy inline
Ten framework korzysta z CSS Variables, responsywnej skali
typograficznej oraz utility spacing. Zawiera komponenty o papierowej estetyce.
<div class="card layered">Zawartość karty</div>
Zmieniaj motyw atrybutem data-theme="dark" na <html>.
<p>Normalny paragraf z <code>kodem inline</code></p>
<p class="text-muted">Wyciszony tekst</p>
<pre><code>Blok kodu</code></pre>
<!-- Utility classes -->
<p class="text-center">Wyśrodkowany</p>
<p class="text-right">Po prawej</p>
🎨 Paleta i zmienne CSS
Główne kolory
:root {
--paper-accent: #346cab;
--paper-accent-hover: #3e79bd;
--paper-success: #28a745;
--paper-warning: #ffc107;
--paper-danger: #dc3545;
--paper-info: #17a2b8;
}
/* W trybie ciemnym automatycznie się zmienią */
[data-theme="dark"] {
--paper-bg: #1a1a1a;
--paper-ink: #e8e4d9;
}
🔘 System przycisków
Podstawowe przyciski
<button class="btn">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-outline">Outline</button>
<button class="btn btn-ghost">Ghost</button>
Warianty kolorów
<button class="btn btn-success">Success</button>
<button class="btn btn-info">Info</button>
<button class="btn btn-warning">Warning</button>
<button class="btn btn-danger">Danger</button>
<!-- Można łączyć z outline -->
<button class="btn btn-outline btn-success">Outline Success</button>
Specjalne efekty
<button class="btn btn-ok">OK</button>
<button class="btn btn-cancel">Anuluj</button>
<button class="btn btn-premium">Premium</button>
<button class="btn btn-glow">Świecący</button>
<button class="btn btn-3d">3D</button>
<!-- Można łączyć efekty -->
<button class="btn btn-success btn-glow">Success + Glow</button>
🧩 Główne komponenty
Badge & Alerty
Tekst z Nowe oraz Info
Powiadomienia (toasty) w stylu e-ink:
<!-- Badge -->
<span class="badge">Nowe</span>
<span class="badge-outline">Info</span>
<!-- Alerty -->
<div class="alert">Alert podstawowy</div>
<div class="alert alert-success">Alert sukcesu</div>
<div class="alert alert-warning">Alert ostrzeżenia</div>
<div class="alert alert-danger">Alert błędu</div>
<!-- Toast (JavaScript) -->
<script>
PaperToast.show('Wiadomość', {title: 'Tytuł'});
PaperToast.success('Sukces!');
PaperToast.error('Błąd!');
</script>
Panel & Karty
Panel
Lekki panel z przerywaną ramką i papierowym tłem.
Paper Edge
Efekt papierowej karty z lekką teksturą i blendem.
<!-- Podstawowa karta -->
<div class="card">
<h3>Tytuł karty</h3>
<p>Zawartość karty</p>
</div>
<!-- Warstwowa karta -->
<div class="card layered">
<h3>Karta z cieniem</h3>
</div>
<!-- Panel -->
<div class="panel">
<p>Panel z przerywaną ramką</p>
</div>
<!-- Paper edge -->
<div class="paper-edge">
<p>Efekt papierowej karty</p>
</div>
Tabs (karty)
Komponent Tabs pozwala przełączać sekcje treści jednym kliknięciem, zachowując czystą strukturę HTML.
<div class="tabs" id="demo-tabs">
<div class="tab-list" role="tablist">
<button role="tab" aria-selected="true" data-tab="tab-1" tabindex="0">Tab 1</button>
<button role="tab" aria-selected="false" data-tab="tab-2" tabindex="-1">Tab 2</button>
</div>
<div id="tab-1" class="tab-panel active" role="tabpanel" aria-hidden="false">
<p>Zawartość pierwszego taba</p>
</div>
<div id="tab-2" class="tab-panel" role="tabpanel" aria-hidden="true">
<p>Zawartość drugiego taba</p>
</div>
</div>
<!-- Obsługa klawiatury WAI-ARIA APG -->
<!-- ← → lub ↑ ↓ : przełączanie między tabami -->
<!-- Home/End : pierwszy/ostatni tab -->
<!-- Enter/Spacja : aktywacja taba -->
<!-- Tab : przenosi fokus do zawartości panelu -->
Accordion
Treść sekcji pierwszej - automatycznie rozwinięta.
Więcej treści – łatwo dodawać kolejne bloki.
<div class="accordion">
<div class="accordion-item">
<h4 class="accordion-header">
<button class="accordion-button" aria-expanded="true">
Tytuł sekcji
</button>
</h4>
<div class="accordion-content open">
<p>Zawartość sekcji</p>
</div>
</div>
</div>
<!-- Klasa "open" = rozwinięta na start -->
Formularze ze stanami
Tabela danych
| # | Nazwa | Status | Tag | Akcje |
|---|---|---|---|---|
| 01 | Element Alfa | Nowy | .alpha |
|
| 02 | Element Beta | Info | .beta |
|
| 03 | Element Gamma | Nowy | .gamma |
Nawigacja Breadcrumb
Modal
Modale są ukryte przez .modal-backdrop i pokazywane przez dodanie klasy
.open. Użyj atrybutu data-open-modal="id".
🔧 Przydatne Komponenty
Toggle Switches
Nowoczesne przełączniki w stylu paper z animacjami.
Podstawowe przełączniki
Rozmiary
<!-- Podstawowy przełącznik -->
<label class="switch">
<input type="checkbox">
<span class="switch-slider"></span>
</label>
<!-- Warianty kolorystyczne -->
<label class="switch switch-success">
<input type="checkbox" checked>
<span class="switch-slider"></span>
</label>
<label class="switch switch-warning">
<input type="checkbox" checked>
<span class="switch-slider"></span>
</label>
<label class="switch switch-danger">
<input type="checkbox" checked>
<span class="switch-slider"></span>
</label>
<label class="switch switch-info">
<input type="checkbox" checked>
<span class="switch-slider"></span>
</label>
<!-- Różne rozmiary -->
<label class="switch switch-sm">
<input type="checkbox">
<span class="switch-slider"></span>
</label>
<label class="switch switch-lg">
<input type="checkbox">
<span class="switch-slider"></span>
</label>
<!-- Wyłączony -->
<label class="switch">
<input type="checkbox" disabled>
<span class="switch-slider"></span>
</label>
Timeline
Oś czasu w stylu papierowym do prezentacji chronologicznej.
<div class="timeline">
<div class="timeline-item">
<div class="timeline-header">
<div class="timeline-title">Tytuł wydarzenia</div>
<div class="timeline-date">Styczeń 2024</div>
</div>
<div class="timeline-content">
Opis wydarzenia w osi czasu.
</div>
</div>
<div class="timeline-item timeline-success">
<div class="timeline-header">
<div class="timeline-title">Sukces</div>
<div class="timeline-date">Marzec 2024</div>
</div>
<div class="timeline-content">
Pozytywne wydarzenie.
</div>
</div>
<div class="timeline-item timeline-warning">
<div class="timeline-header">
<div class="timeline-title">Ostrzeżenie</div>
<div class="timeline-date">Kwiecień 2024</div>
</div>
<div class="timeline-content">
Wydarzenie wymagające uwagi.
</div>
</div>
<div class="timeline-item timeline-danger">
<div class="timeline-header">
<div class="timeline-title">Problem</div>
<div class="timeline-date">Maj 2024</div>
</div>
<div class="timeline-content">
Krytyczne wydarzenie.
</div>
</div>
</div>
Date Picker
Picker dat w stylu papierowym z kalendarzem.
<div class="date-picker">
<input type="text" class="date-picker-input" placeholder="Wybierz datę" readonly>
<div class="date-picker-calendar">
<div class="date-picker-header">
<button class="date-picker-nav" data-action="prev">‹</button>
<div class="date-picker-month"></div>
<button class="date-picker-nav" data-action="next">›</button>
</div>
<div class="date-picker-grid">
<div class="date-picker-weekday">Pn</div>
<div class="date-picker-weekday">Wt</div>
<div class="date-picker-weekday">Śr</div>
<div class="date-picker-weekday">Cz</div>
<div class="date-picker-weekday">Pt</div>
<div class="date-picker-weekday">So</div>
<div class="date-picker-weekday">Nd</div>
<!-- Dni generowane przez JavaScript -->
</div>
</div>
</div>
<!-- Dołącz JavaScript -->
<script src="datepicker.js"></script>
<!-- Automatyczna inicjalizacja - wszystkie .date-picker zostaną aktywne -->
<!-- Lub ręczna inicjalizacja: -->
<script>
// Podstawowe użycie
const picker1 = new PaperDatePicker('#date-input');
// Z opcjami
const picker2 = new PaperDatePicker('#date-input-2', {
format: 'DD.MM.YYYY',
minDate: new Date(),
maxDate: new Date(2025, 11, 31),
onSelect: function(date) {
console.log('Wybrano datę:', date);
}
});
// Ustawienie daty programowo
picker1.setDate(new Date());
// Pobranie wybranej daty
console.log(picker1.getDate());
</script>
Sidebar Navigation
Boczny panel nawigacyjny z animacjami i grupowaniem.
<!-- Przycisk otwierania -->
<button onclick="openSidebar()">Otwórz menu</button>
<!-- Struktura sidebar -->
<div class="sidebar-overlay" id="sidebar-overlay"></div>
<div class="sidebar" id="sidebar">
<div class="sidebar-header">
<h3 class="sidebar-title">Menu</h3>
</div>
<nav class="sidebar-nav">
<div class="sidebar-nav-group">
<div class="sidebar-nav-group-title">Główne</div>
<a href="#" class="sidebar-nav-item active">Dashboard</a>
<a href="#" class="sidebar-nav-item">Projekty</a>
<a href="#" class="sidebar-nav-item">Zadania</a>
</div>
<div class="sidebar-nav-group">
<div class="sidebar-nav-group-title">Ustawienia</div>
<a href="#" class="sidebar-nav-item">Profil</a>
<a href="#" class="sidebar-nav-item">Preferencje</a>
</div>
</nav>
</div>
<!-- JavaScript -->
<script>
function openSidebar() {
document.getElementById('sidebar').classList.add('open');
document.getElementById('sidebar-overlay').classList.add('open');
}
function closeSidebar() {
document.getElementById('sidebar').classList.remove('open');
document.getElementById('sidebar-overlay').classList.remove('open');
}
// Zamknij po kliknięciu w overlay
document.getElementById('sidebar-overlay').addEventListener('click', closeSidebar);
</script>
Zaawansowany Grid System
Rozszerzony system grid z większymi możliwościami layoutu.
Grid z różnymi kolumnami
Span kolumn
<!-- Podstawowe gridy -->
<div class="grid grid-2 gap-3">
<div>Element 1</div>
<div>Element 2</div>
</div>
<div class="grid grid-3 gap-4">
<div>Element 1</div>
<div>Element 2</div>
<div>Element 3</div>
</div>
<!-- Grid z spanowaniem kolumn -->
<div class="grid grid-6 gap-3">
<div class="col-span-2">Zajmuje 2 kolumny</div>
<div class="col-span-3">Zajmuje 3 kolumny</div>
<div>1 kolumna</div>
<div class="col-span-full">Całą szerokość</div>
</div>
<!-- Grid 12-kolumnowy -->
<div class="grid grid-12 gap-2">
<div class="col-span-4">4/12</div>
<div class="col-span-8">8/12</div>
<div class="col-span-6">6/12</div>
<div class="col-span-6">6/12</div>
</div>
<!-- Pozycjonowanie -->
<div class="grid grid-4 gap-2">
<div class="col-start-2 col-span-2">
Zaczyna od 2. kolumny, zajmuje 2
</div>
</div>
<!-- Responsywne - automatycznie dostosowuje się na mniejszych ekranach -->
Motyw & Tryb ciemny
Atrybut data-theme="dark" przełącza paletę. Przycisk w navbarze zapisuje
wybór w localStorage. Wszystkie komponenty, w tym toasty, automatycznie
dostosowują się do motywu papierowego.
Konfiguracja motywu
Przykład JS + CSS do przełączania i zapisywania motywu.
- HTML atrybut:
<html data-theme="light"> - JS przełącza klasę / atrybut i zapisuje preferencję
- Nadpisanie zmiennych poprzedza import stylów (lub ma większą specyficzność)
<html lang="pl" data-theme="light">
...
<button id="themeToggle" class="btn btn-sm">Przełącz motyw</button>
/* CSS (nadpisanie tokenów) */
:root {
--paper-accent: #346cab;
--paper-accent-hover: #3e79bd;
}
[data-theme="dark"] {
--paper-bg: #1a1a1a;
--paper-ink: #e8e4d9;
}
// JS (persistencja)
const root = document.documentElement;
const saved = localStorage.getItem('theme');
if (saved) root.setAttribute('data-theme', saved);
document.getElementById('themeToggle').addEventListener('click', () => {
const next = root.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
root.setAttribute('data-theme', next);
localStorage.setItem('theme', next);
PaperToast.show(`Motyw: ${next}`, { title: 'Theme' });
});
Nadpisywanie zmiennych
:root {
--paper-accent: #346cab;
--paper-accent-hover: #3e79bd;
}
Test w trybie ciemnym
Przełącz motyw przyciskiem w navbar i przetestuj toasty:
Nowe Komponenty
Skeleton Loading
To jest normalna treść z tekstem i obrazami.
Więcej treści do ukrycia za skeleton.
<!-- HTML - kontener z treścią -->
<div id="content-demo">
<p>Treść do ukrycia za skeleton</p>
<div class="user-avatar"></div>
<p>Więcej zawartości</p>
</div>
<!-- Przyciski sterujące -->
<button onclick="PaperSkeleton.show('#content-demo')">
Pokaż skeleton
</button>
<button onclick="PaperSkeleton.hide('#content-demo')">
Ukryj skeleton
</button>
<!-- JavaScript API -->
<script>
// Pokaż skeleton na elemencie
PaperSkeleton.show('#content-demo');
// Ukryj skeleton i przywróć zawartość
PaperSkeleton.hide('#content-demo');
// Automatyczne ukrycie po czasie
setTimeout(() => PaperSkeleton.hide('#content-demo'), 3000);
</script>
Offcanvas Panel
Panel wysuwany z boku ekranu z animacją i blokadą scrolla.
<!-- Przycisk otwierający panel -->
<button class="btn btn-primary" data-open-offcanvas="demo-offcanvas">
Otwórz panel
</button>
<!-- Struktura panelu offcanvas -->
<div class="offcanvas-backdrop" id="demo-offcanvas-backdrop">
<div class="offcanvas" id="demo-offcanvas">
<div class="offcanvas-header">
<h3>Tytuł panelu</h3>
<button class="offcanvas-close btn-ghost">×</button>
</div>
<div class="offcanvas-body">
<p>Zawartość panelu bocznego</p>
<ul>
<li>Opcja 1</li>
<li>Opcja 2</li>
<li>Opcja 3</li>
</ul>
<div class="mt-4">
<button class="btn btn-primary">Zapisz</button>
<button class="btn btn-outline">Anuluj</button>
</div>
</div>
</div>
</div>
<!-- JavaScript - automatyczne działanie z data-open-offcanvas -->
Dropdown Menu
Menu rozwijane z obsługą klawiatury i animacjami.
<!-- Dropdown z przyciskiem i menu -->
<div class="dropdown">
<button class="btn btn-secondary" data-dropdown-toggle>
Menu opcji ▼
</button>
<ul class="dropdown-menu">
<li><a href="#" class="dropdown-item">⚙️ Ustawienia</a></li>
<li><a href="#" class="dropdown-item">👤 Profil</a></li>
<li><hr class="dropdown-divider"></li>
<li><a href="#" class="dropdown-item">🚪 Wyloguj</a></li>
</ul>
</div>
<!-- Różne style przycisków -->
<div class="dropdown">
<button class="btn btn-outline" data-dropdown-toggle>
Więcej ⋯
</button>
<ul class="dropdown-menu">
<li><a href="#" class="dropdown-item">Edytuj</a></li>
<li><a href="#" class="dropdown-item">Usuń</a></li>
</ul>
</div>
<!-- Automatyczna obsługa przez data-dropdown-toggle -->
Chip/Tag System
Interaktywne tagi z możliwością usuwania i różnymi stylami.
<!-- Grupa tagów/chipów -->
<div class="chip-group">
<!-- Podstawowy chip -->
<div class="chip">
<span>React</span>
<button class="chip-close">×</button>
</div>
<!-- Chip z obramowaniem -->
<div class="chip chip-outlined">
<span>JavaScript</span>
<button class="chip-close">×</button>
</div>
<!-- Mały chip -->
<div class="chip chip-small">
<span>CSS</span>
<button class="chip-close">×</button>
</div>
<!-- Chip bez przycisku zamknij -->
<div class="chip">
<span>HTML</span>
</div>
</div>
<!-- JavaScript dla usuwania chipów -->
<script>
// Automatyczne usuwanie chipów po kliknięciu .chip-close
document.addEventListener('click', (e) => {
if (e.target.classList.contains('chip-close')) {
e.target.closest('.chip').remove();
}
});
</script>
Progress Bars
Paski postępu z animowanym wypełnianiem i różnymi stylami.
Podstawowe paski postępu
Paski z etykietami
Paski cienkie
<!-- Podstawowy pasek postępu -->
<div class="progress-container">
<div class="progress-bar" id="progress1" style="width: 0%"></div>
</div>
<!-- Pasek z wariantami kolorów -->
<div class="progress-container">
<div class="progress-bar progress-success" style="width: 75%"></div>
</div>
<div class="progress-container">
<div class="progress-bar progress-warning" style="width: 60%"></div>
</div>
<div class="progress-container">
<div class="progress-bar progress-danger" style="width: 30%"></div>
</div>
<!-- Pasek z etykietą -->
<div class="flex justify-between items-center mb-1">
<label class="text-sm text-muted">Pobieranie pliku</label>
<span class="text-sm text-muted" id="progress-label">0%</span>
</div>
<div class="progress-container">
<div class="progress-bar progress-info" id="progress" style="width: 0%"></div>
</div>
<!-- Cienkie paski -->
<div class="progress-container progress-thin">
<div class="progress-bar" style="width: 40%"></div>
</div>
<div class="progress-container progress-xs">
<div class="progress-bar progress-success" style="width: 70%"></div>
</div>
<!-- JavaScript API -->
<script>
// Animowanie paska postępu
PaperProgress.animate('#progress', 75, 2000);
// Z callback po zakończeniu
PaperProgress.animate('#progress', 100, 1500, () => {
console.log('Postęp zakończony!');
});
</script>
Dodatkowe Komponenty
Tooltip System
Wskazówki kontekstowe wyświetlane przy najechaniu myszą lub focus klawiatury.
Podstawowe tooltipsy
Inne elementy z tooltipami
Tooltipsy z ikonami
Alert/Banner System
Pagination
Nawigacja między stronami w stylu papierowym.
Search & Filter
Loading States
Różne stany ładowania w stylu e-ink.
Empty State
Brak danych
Nie znaleziono żadnych elementów do wyświetlenia. Dodaj nowy element lub zmień filtry wyszukiwania.
Image Gallery
Responsive Images
Klasy pomocnicze dla obrazów.
.img-paper
.img-rounded
.img-circle