Documentation
¶
Overview ¶
Package gallery ships the importable component catalog that powers the /components showcase on the docs site (examples/site) and any other tool that needs to render every design-system component against an arbitrary theme — most notably the theme-configuration tool that will live inside the gofastr CLI binary (cmd/gofastr), which cannot import examples/.
The catalog is the single source of truth for which components exist and how each one renders with sensible default configuration. It is a sibling of framework/sdkdocs: both compose framework/ui + core-ui/* into a reusable, importable surface. Like sdkdocs, it is deliberately NOT part of framework/uihost — uihost must never import framework/ui (its always-on styles would leak into every host's CSS bundle), and a gallery of pre-canned demos is the opposite of a host's job.
Layering: the package imports only framework/ui, core-ui/*, and core/render. It does not import the framework root facade, framework/crud, framework/entity, or anything higher up the L1–L5 diagram in framework/ARCHITECTURE.md — so it introduces no cycle and is safely importable from cmd/gofastr, examples/site, and host apps alike.
Three of the 141 entries (sortablelist, optimisticcreate, optimisticdelete) have a live demo that is normally backed by per-visitor session state on the docs site. The gallery catalog ships self-contained seed-rendering Demo closures for them so a theme previewer or static export gets a realistic render out of the box; hosts that wire live session state (like examples/site) call the render helpers in demos.go directly from their own request-bearing SSR path, bypassing the Demo closure.
Index ¶
- Variables
- func BaseCSS(t style.Theme) string
- func Categories() []string
- func CategorySlug(name string) string
- func CodeSnippet(slug string) string
- func ContributeCSS(ss *style.StyleSheet)
- func DemoFor(slug string) func() render.HTML
- func DemoSectionMenuConfig() interactive.SectionMenuConfig
- func IsNoteOnly(slug string) bool
- func OptimisticDeleteModals() []*widget.Builder
- func OptimisticFailDeleteTrigger() render.HTML
- func PkgForSlug(slug string) string
- func RenderKanbanBoard(cols []KanbanColumn, version int) render.HTML
- func RenderOptimisticCreateDemoFor(notes []OptimisticNote) render.HTML
- func RenderOptimisticCreateList(notes []OptimisticNote) render.HTML
- func RenderOptimisticDeleteDemoFor(notes []OptimisticNote) render.HTML
- func RenderOptimisticDeleteList(notes []OptimisticNote) render.HTML
- type Entry
- type Group
- type KanbanCard
- type KanbanColumn
- type OptimisticNote
Constants ¶
This section is empty.
Variables ¶
var Catalog = []Entry{}/* 141 elements not displayed */
Catalog — every component the showcase ships. The source of truth: hosts iterate over it to register routes, the index screen iterates to render cards, and the showcase screen iterates to look up the active entry.
Catalog stays exported (unlike the private codeSnippets / noteOnlySlugs maps) because it is a slice populated at package init and never mutated after: concurrent reads of a stable slice header are safe, and wrapping every iteration site behind a snapshot accessor would add per-call allocation for no practical safety gain. A host that reassigns Catalog after serving begins would race readers — don't.
var DemoCompany = store.New("sitedemo").String("company", "Acme Corp")
DemoCompany is a page-scoped store slice powering the /components/signal-store demo: one producer renames it, every bound consumer updates client-side. Exported so hosts that want to inspect or reset the demo's slice can.
var InitialOptimisticNotes = []OptimisticNote{
{ID: "n1", Title: "Ship the optimistic-ui cookbook"},
{ID: "n2", Title: "Document the mutation lifecycle"},
{ID: "n3", Title: "Pair ConfirmAction with delete"},
}
InitialOptimisticNotes is the snapshot every session's create + delete lists seed from. The delete list only shrinks (via the delete RPC); the create list grows past it as the user clicks Add.
var SidebarShowcaseConfig = ui.SidebarConfig{ Title: "Docs", NavLabel: "Sidebar component example", Variant: ui.SidebarCollapsible, DrawerName: "ui-sidebar-drawer", Items: []ui.SidebarItem{ {Label: "Modeling", Children: []ui.SidebarItem{ {Label: "Entities", Href: "/docs/entities"}, {Label: "Fields", Href: "/docs/fields"}, }}, {Label: "Serving", Children: []ui.SidebarItem{ {Label: "Router", Href: "/docs/router"}, {Label: "Middleware", Href: "/docs/middleware"}, }}, }, }
SidebarShowcaseConfig is the config for the /components/sidebar demo. It is shared between the inline render (the hamburger trigger in the catalog closure) and the mounted ui-sidebar-drawer widget the host mounts once at startup — so the two agree on DrawerName + content, otherwise the hamburger opens a drawer that was never mounted.
Functions ¶
func BaseCSS ¶ added in v0.49.0
BaseCSS renders ContributeCSS against a theme. For consumers that need a CSS string rather than a StyleSheet to build into — uihost.WithCustomCSS, for instance.
func Categories ¶
func Categories() []string
Categories returns the distinct category names in display (catalog) order — the names of Grouped().
func CategorySlug ¶
CategorySlug is a fragment-safe variant of a category name. "Buttons & links" → "buttons-links". Used as both the section <id> and the rail-link href so the anchor-scroll actually lands. Without this, hrefs end up like "#Buttons & links" which the browser silently ignores.
func CodeSnippet ¶
CodeSnippet returns the example Go source for a component's showcase page, or "" when no snippet is registered. Read through this accessor rather than the private codeSnippets map so the map is never exposed as a mutable global to request handlers.
func ContributeCSS ¶ added in v0.49.0
func ContributeCSS(ss *style.StyleSheet)
ContributeCSS adds the layout classes the catalog's own Demo closures emit.
These are the gallery's contract with itself: a demo that shows three button variants wraps them in `.demo-row`, and one that stacks examples uses `.demo-stack`. The markup lives here, so the rules that make it lay out have to live here too. They were previously written out by hand in examples/site/styles_pages.go, which meant the docs site owned CSS for markup it does not emit — and the moment a second consumer appeared (the theme configurator) the rules were duplicated rather than shared.
This is layout only: flex direction and gap, every value a theme token. No colour, no border, no component styling — a demo's appearance comes from the components it renders, which is the whole point of a gallery.
func DemoFor ¶
DemoFor returns the Demo closure for slug, or nil for an unknown slug.
Hosts whose live demos need per-request session state (e.g. examples/site renders sortablelist/optimisticcreate/optimisticdelete from the visitor's own demoState) switch on the slug in their own SSR path and call the Render* helpers directly.
func DemoSectionMenuConfig ¶
func DemoSectionMenuConfig() interactive.SectionMenuConfig
DemoSectionMenuConfig powers the /components/section-menu showcase — a small self-contained menu whose drawer the host mounts like any real menu's.
func IsNoteOnly ¶
IsNoteOnly reports whether the slug's showcase renders an explanatory note instead of a live demo — those components need per-page backend wiring (an RPC, a mounted widget, image sources) that a self-contained demo cannot provide.
func OptimisticDeleteModals ¶
OptimisticDeleteModals returns one *widget.Builder per initial delete row (the ConfirmAction modal matching that row's Delete trigger), PLUS the opt-delete-fail-n1 modal for the "will fail" affordance. Hosts mount these once at startup, keyed off InitialOptimisticNotes — the set EVERY session seeds from and only ever shrinks below. So every rendered trigger, in any session, has its modal mounted — no orphan opt-delete-nN triggers.
func OptimisticFailDeleteTrigger ¶
OptimisticFailDeleteTrigger is the inline trigger for the "Delete (will fail)" affordance rendered below the list. It opens the dedicated opt-delete-fail-n1 modal (mounted by OptimisticDeleteModals) whose RPC always returns 422 — the runtime then leaves the opt-delete-list region untouched, exercising the optimistic-UI "failed delete leaves the row/list unchanged" invariant. Rendered as a free-standing button (no list row) so the store never carries a phantom "fail row".
func PkgForSlug ¶
PkgForSlug returns the Go source package for a component, used to link the showcase header at its API docs on pkg.go.dev. Most live in framework/ui; a few are core-ui patterns or the image pipeline.
func RenderKanbanBoard ¶
func RenderKanbanBoard(cols []KanbanColumn, version int) render.HTML
RenderKanbanBoard renders N linked sortable columns. Each column shares Group "kanban-demo" and has a unique Container id. Version + ConflictRPC wire the 409 conflict-recovery path. The caller owns any locking around the input data — this function is lock-free.
func RenderOptimisticCreateDemoFor ¶
func RenderOptimisticCreateDemoFor(notes []OptimisticNote) render.HTML
RenderOptimisticCreateDemoFor renders the full optimistic-create demo (code block + Add button + the supplied list) for a given notes slice. The list region is bound to a signal in mode=html; on 2xx the runtime swaps its innerHTML with the response — the fresh authoritative list (with the new row's real server-assigned id). Hosts pass the visitor's current createNotes; the gallery's seed catalog closure passes InitialOptimisticNotes.
func RenderOptimisticCreateList ¶
func RenderOptimisticCreateList(notes []OptimisticNote) render.HTML
RenderOptimisticCreateList renders the create list as a <ul> of rows. Used at SSR and as the create-RPC response body: the runtime swaps the list region's innerHTML with this HTML on 2xx.
func RenderOptimisticDeleteDemoFor ¶
func RenderOptimisticDeleteDemoFor(notes []OptimisticNote) render.HTML
RenderOptimisticDeleteDemoFor renders the full optimistic-delete demo (code block + the supplied list + the will-fail trigger) for a given notes slice. Hosts pass the visitor's current deleteNotes; the gallery's seed catalog closure passes InitialOptimisticNotes.
func RenderOptimisticDeleteList ¶
func RenderOptimisticDeleteList(notes []OptimisticNote) render.HTML
RenderOptimisticDeleteList renders the delete list as a <ul> with a Delete trigger per row. Each trigger is the ConfirmAction trigger for its row's modal (mounted by OptimisticDeleteModals).
Types ¶
type Entry ¶
type Entry struct {
Slug string
Name string
Category string
Desc string
// Demo returns a self-contained render.HTML showing the component live,
// configured with sensible defaults so the page works without setup.
// Closures that need backend wiring (DataTable's RPC island,
// ConfirmAction's modal) render a smaller stand-alone variant or a
// static note — IsNoteOnly reports whether a slug renders an
// explanatory note instead of a live instance (the set itself is
// private; that accessor is the only way in).
Demo func() render.HTML
}
Entry describes one component in the catalog. It is the shape every /components/<slug> page iterates over: main.go registers a route per entry, the index screen renders a card per entry, and the showcase screen looks up the active entry by slug.
func ByCategory ¶
ByCategory returns every entry whose Category matches, in catalog order. Returns nil if the category is unknown.
func Lookup ¶
Lookup returns the entry for slug and ok=true, or the zero Entry and ok=false if the slug is unknown.
func MustLookup ¶
MustLookup returns the entry for slug, panicking if it is unknown. Use only for slugs that are guaranteed by construction (e.g. the slug came from ranging over Catalog itself).
type Group ¶
Group is a category-grouped slice of entries — the shape the index page and the navigation sidebar iterate over. Groups are returned in catalog (display) order.
type KanbanCard ¶
type KanbanCard struct{ Key, Title string }
KanbanCard is one draggable card on the kanban demo board.
type KanbanColumn ¶
type KanbanColumn struct {
ID, Title string
Cards []KanbanCard
}
KanbanColumn is one linked sortable column. A board is a []KanbanColumn.
func InitialKanbanColumns ¶
func InitialKanbanColumns() []KanbanColumn
InitialKanbanColumns is the seed board every visitor's session starts from — and the board the gallery's seed Demo closure renders.
type OptimisticNote ¶
type OptimisticNote struct {
ID, Title string
}
OptimisticNote is one row in the optimistic-create / optimistic-delete demo lists. Each visitor's demoState carries two independent note lists — one per recipe — seeded from InitialOptimisticNotes.