Releases: marilenaRM/turbo-toast-bundle
Releases · marilenaRM/turbo-toast-bundle
Release list
v0.2.1 — Robust toast dismissal
Fixed
- Dismissed toasts could stay in the DOM forever when the consumer app does not load the optional
toast.css(or overrides.toastwithout a transition):transitionendnever fires, so the removal never ran.dismiss()now reads the effective transition duration viagetComputedStyleand removes the element immediately when it is zero, otherwise keeps thetransitionendlistener with asetTimeoutfallback slightly above the duration. This also coversprefers-reduced-motionand interrupted transitions. transitionendbubbling from descendants (custom<template>toasts containing e.g. a progress bar or a button with its own transition) could tear the toast down early. The handler now reacts only to the toast's own transition (event.target === element).- Asymmetric teardown: the
transitionendlistener is now removed indisconnect()too, not just the fallback timer.
Changed
- Controller test suite converted to fake timers — deterministic and ~7× faster — with a new regression test for the descendant-bubbling guard.
Full changelog: v0.2.0...v0.2.1
v0.2.0 — Profiler panel
Added
- Turbo Toast profiler panel: in debug mode, the Symfony profiler shows every toast emitted during the request, per transport (Turbo Stream / cookie), with queued / transported / discarded counts for the cookie path. Discards on server errors are highlighted in the toolbar. Zero overhead outside
kernel.debug— the traceable decorators are only wired there.
Changed
ToastRendererInterfaceandToastStackInterfaceextracted — the trait, the subscriber and the container aliases now target the interfaces. If you were autowiring the concreteToastRenderer/ToastStackclasses, switch your type-hints to the interfaces.
Full changelog: v0.1.4...v0.2.0
v0.1.4 — Customization hooks & observability
Added
- Two customization hooks for cookie-rendered toasts, both XSS-safe:
- a cancelable
…toast-container:appendevent — callpreventDefault()and render with your own toast library - a
<template>target inside the container, cloned per toast — your markup, the message lands as text in[data-toast-message]
- a cancelable
- Optional logging (monolog channel
turbo_toast): warning when queued toasts are discarded on a 5xx or dropped over the cookie size budget (no more silent drops), debug on emission
Changed
- Services now use snake_case ids (
marilena_rm_turbo_toast.*) with class aliases for autowiring — decorate or replace by stable id - Resolved configuration is carried by a
ToastConfigvalue object instead of scalar constructor args loadExtension()parameter names realigned withAbstractBundle(named-arguments safety)ToastStackis now\Countable
Full changelog: v0.1.3...v0.1.4
v0.1.3 — Internal refactor
Changed
- The cookie subscriber discards queued toasts on server errors with
ToastStack::reset()instead of a droppeddrain()— each method now states its intent (reset = throw away, drain = consume). No behavior change.
Full changelog: v0.1.2...v0.1.3
v0.1.2 — Toast dismiss race fix
Fixed
- A dismiss (click or very short delay) racing the
connect()animation frame could re-add the fade-in class after removal, leaving the toast stuck visible with no timer. The pending frame is now cancelled indismiss()anddisconnect().
Added
- 14 Vitest/jsdom tests for both Stimulus controllers, security paths first: tampered cookie payload rendered as inert text (no XSS), cookie cleared before rendering, no replay on Turbo cache restores, type filtering, malformed payload handling,
roleby toast type — plus fade-in/auto-dismiss/click behavior - CI now runs the JS test suite (node 22)
Full changelog: v0.1.1...v0.1.2
v0.1.1 — Maintenance release
Changed
composer fundnow lists the Ko-fi page — funding metadata ships in a tagged version- Cookie subscriber drains the toast stack once (refactor, no behavior change)
Added
- Security & hardening design notes: the full threat model behind every protection
- Twig templates are now linted with
twig-cs-fixer(composerlint:twigscripts + CI step)
Full changelog: v0.1.0...v0.1.1
v0.1.0 — Initial release
Session-free flash/toast notifications for Symfony that keep your pages HTTP-cacheable.
One addFlash() is enough to drag the session into an otherwise stateless page and make it uncacheable by Varnish or your CDN. This bundle takes the flash out of the session entirely.
Features
Two session-free transports
- Turbo Stream —
$this->toast('Item saved')returns atext/vnd.turbo-stream.htmlresponse that appends the toast to the DOM. No redirect, no storage at all. Refuses to render (with an actionableLogicException) when the request does not accept Turbo Streams. - Cookie —
$this->deferToast('Welcome back!')before a classicRedirectResponse: toasts are serialized into a short-lived cookie atkernel.responsetime and consumed client-side on the next page load. The redirected-to page stays cacheable.
Developer experience
TurboToastTraitfor controllers:toast(),toasts(),deferToast(){{ turbo_toast_container() }}Twig function renders the container div with Stimulus values injected from the bundle configuration — PHP config and JS can never drift apart- Two auto-registered Stimulus controllers:
toast(fade-in, auto-dismiss, click to dismiss) andtoast-container(cookie consumption on initial load and everyturbo:load) - Configurable: container id, controller name, default delay, stream template, cookie name
- Optional minimal stylesheet
Hardening
- Cookie:
SameSite=Lax,Secureon HTTPS, ~3.8 KB budget with graceful overflow, cleared before rendering so Turbo cache restores never replay a toast, rendered withtextContentonly (client-modifiable input) - Responses carrying the cookie are forced
privateso theSet-Cookienever enters a shared HTTP cache - 5xx responses discard queued toasts instead of promising success on the next page
ToastStackimplementsResetInterface(kernel.reset): no cross-request leak under FrankenPHP worker mode / RoadRunner / Swoole- Accessibility:
aria-live="polite"container,role="status"/role="alert"by toast type
Requirements
PHP >= 8.3, Symfony 7.x, symfony/ux-turbo + symfony/stimulus-bundle.
Installation
composer require marilenarm/turbo-toast-bundleSee the README for the full documentation, including the honest when (not) to use it section.