Floating notification overlays
Non-blocking floating notifications at 9 screen positions. Info, Success, Warning, Error types. Auto-dismiss, ESC-to-close, and stacked multi-toast support.
composer require sugarcraft/sugar-toast
use SugarCraft\Toast\{Toast, ToastType, Position};
$toast = Toast::new(50) // max width 50
->withPosition(Position::MiddleRight)
->withAllowEscToClose(true);
$toast = $toast->alert(ToastType::Success, 'File saved!');
$toast = $toast->alert(ToastType::Error, 'Connection failed');
$bg = str_repeat("background content\n", 20);
echo $toast->view($bg);
| Class | Method | Description |
|---|---|---|
| Toast | new(int $maxWidth = 50) | Factory — max width in cells |
| Toast | withPosition(Position) | Set screen position (9 positions) |
| Toast | withDuration(?float $seconds) | Auto-dismiss after N seconds (null to disable) |
| Toast | withAllowEscToClose(bool) | Allow Escape key to dismiss active alert |
| Toast | withMaxWidth(int) | Set maximum alert width in cells |
| Toast | withMinWidth(int) | Set minimum alert width in cells |
| Toast | withSymbolSet(SymbolSet) | NerdFont, Unicode, or ASCII symbol sets |
| Toast | withMaxConcurrent(?int) | Cap concurrent alerts (null = unlimited) |
| Toast | withOverflow(Overflow) | Strategy when cap exceeded: DropOldest, DropNewest, Enqueue |
| Toast | withAnimationDuration(float) | Fade animation duration in seconds (stub; CubicBezier deferred) |
| Toast | alert(ToastType|string, string, ?float $expiresAt) | Add alert; string type = case-insensitive lookup; null expiry = never auto-dismisses |
| Toast | progressToast(ToastType|string, string, float $progress, ?float $expiresAt) | Add alert with progress bar (0.0–1.0, clamped); same expiry semantics as alert() |
| Toast | error(string), warning(string), info(string), success(string) | Convenience alert helpers |
| Toast | hasActiveAlert(): bool | Returns true if non-expired alerts are queued |
| Toast | dismiss(), clear(), pruneExpired() | Manage alert lifecycle; dismiss() records non-expired alerts to history |
| Toast | getHistory(): list<Alert> | Return all dismissed alerts recorded since last dismiss() |
| Toast | view(string $background, int $w, int $h): string | Render toast layer over background view |
| Alert | withProgress(float) | Attach progress bar (0.0–1.0, clamped) |
| Alert | withActions(list<Action>) | Attach action buttons |
| Alert | isExpired(): bool | Check expiry |
| Alert | withExpiry(float $duration) | Set expiry from now |
| Action | make(string $label, \Closure(): void $callback) | Factory |
| Action | $label: non-empty-string | User-visible button label (readonly) |
| Action | $callback: \Closure(): void | Invoked when action is triggered (readonly) |
| HistoryLog | push(Alert): self | Append alert, return new immutable log |
| HistoryLog | all(): list<Alert> | Return all recorded alerts |
| HistoryLog | count(): int | Number of recorded entries |
| ToastType | Info, Success, Warning, Error | Toast type constants |
| ToastType | label() | Translated label via Lang::t() (i18n-aware) |
| Position | TopLeft, TopCenter, TopRight, MiddleLeft, MiddleCenter, MiddleRight, BottomLeft, BottomCenter, BottomRight | 9 screen positions |
| Overflow | DropOldest, DropNewest, Enqueue | Overflow strategy when maxConcurrent is exceeded |
| SymbolSet | NerdFont, Unicode, ASCII | Symbol set for alert icons |
| Lang | t(key, params) | Translate a string: 'dismiss', 'count', 'type.*' |
User-facing strings use SugarCraft\Toast\Lang::t(). All keys are in lang/en.php under the toast namespace.
| Key | Default | Parameters |
|---|---|---|
| type.info / type.warning / type.error / type.success | Info / Warning / Error / Success | — |
| dismiss | Press any key to dismiss | — |
| count | {count} notification(s) | {count} |
To localize, copy lang/en.php to lang/<code>.php and translate the values.
VHS-recorded GIFs of every example shipped with the library. Regenerated automatically on every push that touches the source.