๐ฌ Feedback & Notifications
Components for user notifications, contextual information, loading states, and tooltips.
๐ ToastContainer
Global container for toast notifications (success, error, info, warning). Components never
mount it: they call the store toasts (lib/stores/app/toastStore.svelte.ts).
import {toasts} from '$lib/stores/app/toastStore.svelte';
toasts.success('Saved');
toasts.error('Sync failed', 20000); // custom duration in ms
- Position: stacked at the top centre of the viewport (
fixed top-4 left-1/2 -translate-x-1/2,z-[9999]), newest last, each sliding in from above. - Auto-dismiss after a per-variant default โ success and info 8 s, warning 10 s, error 15 s โ
or the
durationpassed to the call; a thin bar counts the time down. A duration of0keeps the toast until it is dismissed. - Dismiss: the โ button (
toast-dismiss), which stays the keyboard- and screen-reader path, or a swipe of at least 60 px left, right or up (pointer events: finger, pen and mouse). - Color-coded by variant, with a matching icon; test ids
toast-{variant}. - The store also offers
show(variant, message, duration?),dismiss(id)andclear(); toasts are cleared when the signed-in account changes (client-session reset, e.g. logout).
๐งผ HTML messages
A message may contain markup โ flags, coloured badges, icons, links โ and is rendered with
{@html sanitizeHtml(message)} (lib/utils/core/sanitizeHtml.ts, DOMPurify): the markup is kept,
event-handler attributes, <script> and javascript: URLs are dropped. Sanitising is the safety
net, not a licence: escape any user or provider text you put into a message with escapeHtml.
Links inside a toast work like normal links. A press that starts on a link (or a button) never
starts a swipe, so tapping it navigates instead of dragging the toast away. Build links to detail
pages with entityDetailLinkHtml({kind: 'asset', id} | {kind: 'fx', slug}, label)
(lib/utils/core/entityLink.ts): it accepts only those two routes and escapes the label.
ToastContainer.test.ts covers both contracts.
Used by: mounted once in the authenticated layout, routes/(app)/+layout.svelte.
โน๏ธ InfoBanner
An inline banner for contextual information or warnings (ui/feedback/InfoBanner.svelte).
variant:info(default),warning,error,successโ colours and default icon (showIcon, defaulttrue)- Content from
messageor from the children; withmessage, the banner hides itself when the value is empty ornull dismissibleadds an โ that callsondismissrole="alert"forerror,role="status"otherwise; test idinfo-banner-{variant}- Inline within page content (not a toast)
Used by: BrokerModal (validation errors), settings tabs, the
sync and import modals, RegisterCard.
๐ก๏ธ DataQualityBanner
The unified data quality banner component for surfacing data warnings across the dashboard, asset detail, and forex detail pages. Replaces ad-hoc inline banners with a standardized DataQualityIssue model.
See DataQualityBanner Developer Manual for full documentation.
Modes:
groupedโ dashboard: single container with all issues sorted by severityflatโ detail pages: one banner per issue
CTA: actions are emitted via onaction(action, target, issue) โ the component does not navigate or open modals directly.
Used by: Dashboard (/dashboard), Asset detail (/assets/:id), FX detail (/fx/:pair), and the risk panels (RiskAnalysisPanel, AssetSetRiskPanel, RiskPanelHeader).
โณ LoadingSpinner
A simple animated spinner for async loading states (ui/feedback/LoadingSpinner.svelte).
size:sm,md(default),lgโ the vertical padding around ittextbelow the spinner, defaulting to the translatedcommon.loadingrole="status",aria-live="polite"
Used by: API calls, lazy-loaded content, search results.
๐ก Tooltip
Hover/tap tooltip with automatic positioning (ui/feedback/Tooltip.svelte).
- Content:
text, orhtml(rendered throughsanitizeHtml);mathrenders inline$โฆ$LaTeX with KaTeX - Positions:
top(default),bottom,left,rightโ flips when it would leave the viewport; the tooltip is moved todocument.bodyand drawn with fixed positioning, so a modal's overflow or a parent's opacity never affects it - Plain hover opens after
showDelayMs(default 500 ms), so crossing the page does not flash tooltips; a click, a tap or Enter/Space on the focused trigger opens it at once and pins it - A pinned tooltip stays while the pointer is on the trigger or on the tooltip itself; it closes on a second click on the trigger, on a click outside, or 30 s after contact ends
interactiveChild: when the child is itself a button or a link, the wrapper does not add its ownrole="button"and tab stop
Used by: Toolbar buttons, icon-only buttons, info badges, DocsLink.