Components
Overlay
Components that appear on top of the page content — dialogs, modals, drawers, and popovers built on the native <dialog> element or positioned anchoring.
Dialog
Small, centered confirmation dialog for notices, confirmations, warnings, and success celebrations. Built on the native <dialog> element.
Info (default)
dialog-default.blade.php
@use('Pajak\Ui\Common\Enums\Dialog\DialogType')
<x-pajak::dialog id="demo-dialog-info" :type="DialogType::Info" title="Your session has ended">
<x-slot:description>For your security, you've been signed out after 30 minutes of inactivity.</x-slot:description>
<x-slot:actions>
<x-pajak::button>Sign in again</x-pajak::button>
</x-slot:actions>
</x-pajak::dialog>
<button class="pajak-btn pajak-btn--secondary" data-pajak-dialog-trigger="demo-dialog-info">Open info dialog</button>
Types
dialog-types.blade.php
@use('Pajak\Ui\Common\Enums\Dialog\DialogType')
@use('Pajak\Ui\Common\Enums\Variant')
<x-pajak::dialog id="demo-dialog-success" :type="DialogType::Success" title="Return submitted">
<x-slot:description>Your PIT-37 was filed successfully. A confirmation has been sent to your email.</x-slot:description>
<x-slot:actions>
<x-pajak::button>Done</x-pajak::button>
</x-slot:actions>
</x-pajak::dialog>
<x-pajak::dialog id="demo-dialog-warning" :type="DialogType::Warning" title="Missing required field" :stacked="true">
<x-slot:description>You haven't entered your PESEL number. Add it before submitting.</x-slot:description>
<x-slot:actions>
<x-pajak::button>Add PESEL now</x-pajak::button>
<x-pajak::button :variant="Variant::Ghost">Continue anyway</x-pajak::button>
</x-slot:actions>
</x-pajak::dialog>
<x-pajak::dialog id="demo-dialog-danger" :type="DialogType::Danger" title="Discard unsaved changes?">
<x-slot:description>You've edited this return but haven't saved. Leaving now will lose your changes.</x-slot:description>
<x-slot:actions>
<x-pajak::button :variant="Variant::Ghost" data-pajak-dialog-trigger="demo-dialog-danger">Keep editing</x-pajak::button>
<x-pajak::button :variant="Variant::Danger">Discard</x-pajak::button>
</x-slot:actions>
</x-pajak::dialog>
<div class="ex-row">
<button class="pajak-btn pajak-btn--secondary" data-pajak-dialog-trigger="demo-dialog-success">Success</button>
<button class="pajak-btn pajak-btn--secondary" data-pajak-dialog-trigger="demo-dialog-warning">Warning</button>
<button class="pajak-btn pajak-btn--secondary" data-pajak-dialog-trigger="demo-dialog-danger">Danger</button>
</div>
Modal
Larger overlay dialog with icon, title, scrollable body, and footer action bar. Also supports a bottom-sheet variant. Built on the native <dialog> element.
Default
modal-default.blade.php
@use('Pajak\Ui\Common\Enums\Variant')
<x-pajak::modal id="demo-modal-default" title="Submit your tax return?">
<x-slot:description>Once submitted, your PIT-37 will be sent to the tax office. This action cannot be undone.</x-slot:description>
<x-slot:footer>
<x-pajak::button :variant="Variant::Ghost" data-pajak-modal-close>Cancel</x-pajak::button>
<x-pajak::button>Submit return</x-pajak::button>
</x-slot:footer>
</x-pajak::modal>
<button class="pajak-btn pajak-btn--secondary" data-pajak-modal-trigger="demo-modal-default">Open modal</button>
Sizes & sheet variant
modal-sizes.blade.php
@use('Pajak\Ui\Common\Enums\Modal\ModalSize')
@use('Pajak\Ui\Common\Enums\Variant')
<x-pajak::modal id="demo-modal-sm" :size="ModalSize::Sm" title="Quick confirmation">
<x-slot:description>Are you sure you want to proceed?</x-slot:description>
<x-slot:footer>
<x-pajak::button :variant="Variant::Ghost" data-pajak-modal-close>Cancel</x-pajak::button>
<x-pajak::button>Confirm</x-pajak::button>
</x-slot:footer>
</x-pajak::modal>
<x-pajak::modal id="demo-modal-lg" :size="ModalSize::Lg" title="Review income sources">
<x-slot:description>We found 3 income sources from your PIT-11. Review them before continuing.</x-slot:description>
<p class="ex-p">Salary · Acme Sp. z o.o. · PLN 84,000</p>
<x-slot:footer>
<x-pajak::button :variant="Variant::Ghost" data-pajak-modal-close>Edit</x-pajak::button>
<x-pajak::button>Confirm all</x-pajak::button>
</x-slot:footer>
</x-pajak::modal>
<x-pajak::modal id="demo-modal-sheet" :sheet="true" title="Sign with mObywatel?">
<x-slot:description>You'll be redirected to the mObywatel app to confirm and sign your return.</x-slot:description>
<x-slot:footer>
<x-pajak::button :variant="Variant::Ghost" data-pajak-modal-close>Not now</x-pajak::button>
<x-pajak::button>Continue</x-pajak::button>
</x-slot:footer>
</x-pajak::modal>
<div class="ex-row">
<button class="pajak-btn pajak-btn--secondary" data-pajak-modal-trigger="demo-modal-sm">Small</button>
<button class="pajak-btn pajak-btn--secondary" data-pajak-modal-trigger="demo-modal-lg">Large</button>
<button class="pajak-btn pajak-btn--secondary" data-pajak-modal-trigger="demo-modal-sheet">Sheet</button>
</div>
Dynamic content (single modal, multiple triggers)
modal-dynamic.blade.php
@use('Pajak\Ui\Common\Enums\Variant')
<x-pajak::modal id="demo-modal-dynamic" title="">
<x-slot:description></x-slot:description>
<x-slot:footer>
<x-pajak::button :variant="Variant::Ghost" data-pajak-modal-close>Cancel</x-pajak::button>
<x-pajak::button>Send invoice</x-pajak::button>
</x-slot:footer>
</x-pajak::modal>
<div class="ex-row">
<button class="pajak-btn pajak-btn--secondary"
data-dynamic-modal-trigger="demo-modal-dynamic"
data-modal-title="Send INV-001"
data-modal-description="Send this invoice to <strong>Acme Sp. z o.o.</strong> They will receive an email with a payment link.">
INV-001
</button>
<button class="pajak-btn pajak-btn--secondary"
data-dynamic-modal-trigger="demo-modal-dynamic"
data-modal-title="Send INV-002"
data-modal-description="Send this invoice to <strong>Beta Consulting</strong> They will receive an email with a payment link.">
INV-002
</button>
<button class="pajak-btn pajak-btn--secondary"
data-dynamic-modal-trigger="demo-modal-dynamic"
data-modal-title="Send INV-003"
data-modal-description="Send this invoice to <strong>Gamma Ltd.</strong> They will receive an email with a payment link.">
INV-003
</button>
</div>
Drawer
A panel that slides in from a viewport edge. Use for filter panels, navigation, detail views, and quick-action sheets. Built on the native <dialog> element.
Default (right)
drawer-default.blade.php
@use('Pajak\Ui\Common\Enums\Variant')
<x-pajak::drawer id="demo-drawer-default" title="Filter deductions">
<x-slot:description>12 results across 4 categories</x-slot:description>
<div class="ex-drawer-list">
<label class="ex-drawer-label">
<input type="checkbox" checked> Employment income
</label>
<label class="ex-drawer-label">
<input type="checkbox"> Rental income
</label>
<label class="ex-drawer-label">
<input type="checkbox" checked> Deductible expenses
</label>
<label class="ex-drawer-label">
<input type="checkbox"> Exemptions
</label>
</div>
<x-slot:footer>
<x-pajak::button :variant="Variant::Ghost" data-pajak-drawer-close>Reset</x-pajak::button>
<x-pajak::button>Apply (3)</x-pajak::button>
</x-slot:footer>
</x-pajak::drawer>
<button class="pajak-btn pajak-btn--secondary" data-pajak-drawer-trigger="demo-drawer-default">Open filter drawer</button>
Sides — left, bottom, top
drawer-sides.blade.php
@use('Pajak\Ui\Common\Enums\Drawer\DrawerSide')
@use('Pajak\Ui\Common\Enums\Variant')
<x-pajak::drawer id="demo-drawer-left" :side="DrawerSide::Left" title="Navigation">
<x-slot:description>Tax year 2025</x-slot:description>
<p class="ex-p ex-slot-text">Left drawer — 280 px, slides from the left edge. Use for navigation panels.</p>
</x-pajak::drawer>
<x-pajak::drawer id="demo-drawer-bottom" :side="DrawerSide::Bottom" title="Refund details">
<x-slot:description>PIT-37 — 2025</x-slot:description>
<p class="ex-p ex-slot-text">Bottom sheet — full width, max 80 vh, includes a grabber at the top.</p>
<x-slot:footer>
<x-pajak::button :variant="Variant::Ghost" data-pajak-drawer-close>Edit</x-pajak::button>
<x-pajak::button>Submit</x-pajak::button>
</x-slot:footer>
</x-pajak::drawer>
<x-pajak::drawer id="demo-drawer-top" :side="DrawerSide::Top" title="System notice">
<p class="ex-p ex-slot-text">Top drawer — full width, auto height. Use for announcements or quick notices.</p>
</x-pajak::drawer>
<div class="ex-row">
<button class="pajak-btn pajak-btn--secondary" data-pajak-drawer-trigger="demo-drawer-left">Left</button>
<button class="pajak-btn pajak-btn--secondary" data-pajak-drawer-trigger="demo-drawer-bottom">Bottom</button>
<button class="pajak-btn pajak-btn--secondary" data-pajak-drawer-trigger="demo-drawer-top">Top</button>
</div>
Popover
A positioned overlay panel anchored to a trigger element. Supports five placement variants, an optional title, and head/body/foot slot layout.
Default
popover-default.blade.php
@use('Pajak\Ui\Common\Enums\Variant')
@use('Pajak\Ui\Common\Enums\Size')
<div class="ex-popover-wrap">
<button class="pajak-btn pajak-btn--secondary" data-pajak-popover-trigger="demo-pop-default" aria-expanded="false" aria-haspopup="true">
Open popover
</button>
<x-pajak::popover id="demo-pop-default" title="Polish tax bracket">
Your income up to <strong>120 000 zł</strong> is taxed at <strong>17%</strong>.
Income above that threshold is taxed at 32%.
<x-slot:footer>
<x-pajak::button :variant="Variant::Ghost" :size="Size::Sm" data-pajak-popover-close>Got it</x-pajak::button>
<x-pajak::button :size="Size::Sm">Learn more</x-pajak::button>
</x-slot:footer>
</x-pajak::popover>
</div>
Placement variants
popover-placements.blade.php
@use('Pajak\Ui\Common\Enums\Popover\PopoverPlacement')
<div class="ex-row">
<div class="ex-popover-wrap">
<button class="pajak-btn pajak-btn--secondary" data-pajak-popover-trigger="demo-pop-top" aria-expanded="false" aria-haspopup="true">Top</button>
<x-pajak::popover id="demo-pop-top" :placement="PopoverPlacement::Top">
Arrow points downward — use above a trigger.
</x-pajak::popover>
</div>
<div class="ex-popover-wrap">
<button class="pajak-btn pajak-btn--secondary" data-pajak-popover-trigger="demo-pop-right" aria-expanded="false" aria-haspopup="true">Right</button>
<x-pajak::popover id="demo-pop-right" :placement="PopoverPlacement::Right">
Arrow points left — use to the right of a trigger.
</x-pajak::popover>
</div>
<div class="ex-popover-wrap">
<button class="pajak-btn pajak-btn--secondary" data-pajak-popover-trigger="demo-pop-left" aria-expanded="false" aria-haspopup="true">Left</button>
<x-pajak::popover id="demo-pop-left" :placement="PopoverPlacement::Left">
Arrow points right — use to the left of a trigger.
</x-pajak::popover>
</div>
<div class="ex-popover-wrap">
<button class="pajak-btn pajak-btn--secondary" data-pajak-popover-trigger="demo-pop-bottom-end" aria-expanded="false" aria-haspopup="true">Bottom-end</button>
<x-pajak::popover id="demo-pop-bottom-end" :placement="PopoverPlacement::BottomEnd" title="Bottom-end">
Arrow at the top-right corner.
</x-pajak::popover>
</div>
</div>