sgcHTML Feedback and Media
Thirteen widgets for telling the user something and for showing media: modals, toasts, snackbars, notifications, popovers, placeholders, spinners, badges, chips, avatars, images, video and carousels.
Read sgcwebsockets-html-core first for the page builder and the edition gate.
sgcHTML is All-Access only, needs Indy, and is absent on Android and iOS.
When to use this skill
- Interrupt with a modal dialog, or confirm an action
- Confirm something happened with a toast, a snackbar or a notification
- Explain a control in place with a popover
- Show that something is loading, with a spinner or a placeholder skeleton
- Label or tag with a badge or a chip
- Show a person with an avatar, or media with an image, video or carousel
Components in this skill
| Group | Components |
|---|---|
| Interrupt | _Modal |
| Transient feedback | _Toast, _Snackbar, _Notification |
| In-place help | _Popover |
| Loading | _Spinner, _Placeholder |
| Labels | _Badge, _Chip, _Avatar |
| Media | _Image, _Video, _Carousel |
All are prefixed TsgcHTMLComponent_.
Quickstart, a modal
A modal is a title, a body, a footer and an id. The id matters, because it is what the trigger refers to:
FModal := TsgcHTMLComponent_Modal.Create(Self);
FModal.PageBuilder := FPage;
FModal.ModalID := 'confirm-delete';
FModal.Title := 'Delete customer';
FModal.Body := 'This cannot be undone.';
FModal.Size := msDefault;
FModal.Centered := True;
FModal.StaticBackdrop := True; // clicking outside will not dismiss it
FModal.AddFooterButton('Cancel', bsSecondary, True);
FModal.AddFooterButton('Delete', bsDanger, False);
AddFooterButton's third argument decides whether the button closes the modal
on click. Set it True for cancel, False for the action button, so the modal
stays open while the action runs.
StaticBackdrop := True is worth setting on anything destructive. Without it a
stray click outside dismisses the dialog, which reads as the action being
cancelled when nothing was decided at all.
Picking the right feedback widget
The four look similar and mean different things:
- Modal blocks. Use it when the user must decide before continuing.
- Toast and Snackbar are transient and non-blocking. Use them to confirm something that already happened.
- Notification persists until dismissed. Use it for something that still needs attention.
Reaching for a modal to say "saved" trains people to dismiss dialogs without reading them, which then costs you the one that mattered.
Loading states
_Spinner says "something is happening". _Placeholder renders a skeleton in
the shape of the content that is coming, which reads better when the layout is
known in advance. Both pair naturally with HTMX from
sgcwebsockets-html-core, where a fragment is swapped once its content arrives.
Colours mean things
These widgets take TsgcHTMLColor: (hcPrimary, hcSecondary, hcSuccess, hcDanger, hcWarning, hcInfo, hcLight, hcDark, hcWhite, hcMuted). Buttons take
TsgcHTMLButtonStyle, which follows the same Bootstrap naming.
Use them semantically. hcDanger on a badge that is merely decorative makes
every real warning on the page weaker.
Before you start, ask the developer
Use a structured question tool if your host has one, for example Claude Code's
AskUserQuestion. Otherwise ask in chat:
- Blocking or not? That single answer picks between a modal and everything else in this skill.
- Does it need to survive a page change? Toasts and snackbars do not. A notification that must persist has to be stored somewhere and re-rendered.
- What triggers it? These render markup. Showing a modal in response to a server event needs either a page render that includes it or an HTMX swap.
Things that catch people out
- Every widget needs
PageBuilderassigned, as everywhere in the pack. ModalIDmust be unique on the page and stable between renders. Two modals sharing an id means the wrong one opens.- These render the markup for the component. They do not open it. Opening is a
client-side action, which is why
OnClickon the sgcHTML widgets is a string of JavaScript rather than a Delphi event. - A modal with no footer button and
StaticBackdrop := Truecannot be dismissed. Always give the user a way out. _Videoand_Imagereference a URL. That file has to be served from somewhere, and cross-origin media can be blocked, so same-origin is the simplest path.- A carousel that auto-advances is hostile to anyone reading slowly. If the content matters, let the user drive it.
Routing
- Find a component:
reference/components-index.mdlists every component, itsunit, and its edition, grouped by Reg module. - Uses clause: add the component's
unit:value (shown on its API page) to yourusesclause. Nothing compiles without it. - API detail:
reference/api/<Component>.mdhas the Properties, Events and Methods, each in both Delphi and C++Builder form. - Option / enum / event types: property and event types link to
reference/types/<TypeName>.md, which documents the sub-properties of option classes, the values of enums, and the parameter list of event handlers. - Examples:
examples/index.mdis the full demo catalog;examples/<Component>.mdis a focused, real usage snippet for the most-used components. - Concepts:
concepts/overview.md(getting started + uses-clause rule) andconcepts/editions-and-features.md(which components your edition includes). - Bundled resources:
concepts/resources.mdlists the browser-side assets (JavaScript, HTML, CSS) the server components serve or embed, so a browser client works without an external CDN. - Version history:
reference/history.mdlists what changed in each sgcWebSockets release.
Editions
Components are gated by edition (Professional, Enterprise, All-Access) or by a feature define. Check the edition column in the components index, or concepts/editions-and-features.md, before relying on a component.
Only public and published members are documented. Method bodies, private fields and protected members are intentionally not included.