Documentation
¶
Overview ¶
Package ui holds the typed shapes of the admin partials (web/admin/partials). Templates may use either these structs or plain dicts; handlers build the structs so a misspelt field is a compile error, not an empty cell.
Index ¶
- type Action
- type AiaAgentGroup
- type AiaAgentRow
- type AiaAgents
- type AiaAttention
- type AiaCell
- type AiaChart
- type AiaOtherPurpose
- type AiaPolicy
- type AiaPolicyForm
- type AiaPolicyOnly
- type AiaRows
- type Badge
- type Bar
- type BarItem
- type BarList
- type BarRow
- type BulkAction
- type Button
- type ButtonMenu
- type Callout
- type CategoryBar
- type CategoryMarker
- type CategorySeg
- type CategorySegment
- type Cell
- type Chip
- type Col
- type ConfirmHidden
- type Confirmcard
- type Crumb
- type DangerConfirm
- type DangerPart
- type DangerText
- type DataRow
- type DataTable
- type DateCompare
- type DatePreset
- type DateRange
- type Dropzone
- type Empty
- type FieldError
- type Filter
- type Option
- type PageLink
- type Pagination
- type Progress
- type RadioCard
- type RadioCardItem
- type Row
- type Savestate
- type Secret
- type Segmented
- type SegmentedItem
- type Spark
- type SparkLive
- type Stat
- type StatChange
- type Step
- type Tab
- type TabMore
- type Table
- type Tracker
- type TrackerBlock
- type TrackerKey
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Action ¶
type Action struct {
Label string
Href string
Post string // form action; the CSRF token is added
Icon string // optional icon name shown before the label in a row menu
Danger bool
NewTab bool // open Href in a new tab (a link menu item only)
Fields map[string]string // hidden fields sent with a Post action
// Confirm makes the action ask first. Href is then the confirmation page
// (works without JavaScript) and Post the action the page submits; with JS
// the link opens a native <dialog> showing Confirm instead of navigating.
Confirm string
ConfirmLabel string // the dialog's confirm button (default: Label)
}
Action is a row or overflow-menu action: a link (Href) or a POST form (Post).
type AiaAgentGroup ¶
type AiaAgentGroup struct {
Purpose, Description string
Summary string // "27,997 fetches, 50% of all AI fetches."
Policy *AiaPolicy // the group's Allow / Block control; nil shows none
Rows []AiaAgentRow
// PolicyOnly are robots.txt names that never fetch (Google-Extended).
PolicyOnly []AiaPolicyOnly
}
AiaAgentGroup is one purpose of the agents table: its name, what it means, the totals sentence and the agents that fetched under it.
type AiaAgentRow ¶
type AiaAgentRow struct {
Name, Href, Operator string
Fetches string
Verification Badge
Blocked, Ignores bool // blocked by the purpose's policy; ignores robots.txt
// Purpose is the purpose id the row sits under (policy.js shows "Blocked by
// policy" from it); Fetched is true when the agent fetched in the range.
Purpose string
Fetched bool
LastSeen string
}
AiaAgentRow is one agent. Share is its fetches as a percent of the group's busiest agent (the mini bar); Verification is the badge ("13 spoofed").
type AiaAgents ¶
type AiaAgents struct {
Caption string
Groups []AiaAgentGroup
// Other are the non-AI purposes (search, social, SEO, archive).
Other []AiaOtherPurpose
}
AiaAgents is hm/aia-agents: the agents of one range, one table with a group per AI purpose, then the non-AI purposes as a list.
type AiaAttention ¶
type AiaAttention struct {
Sev int
Count, Text, Rate string
Note string // muted line under the rate
Href, Action string // link and its label ("Review spoofed")
}
AiaAttention is one cell of hm/aia-attention. Sev is 0 (nothing to do), 1 (review) or 2 (act now); the badge word and colour follow it. The link shows only when Sev is above zero.
func (AiaAttention) Badge ¶
func (a AiaAttention) Badge() Badge
Badge is the status badge of the cell.
type AiaCell ¶
type AiaCell struct {
Text, Href, Mono string
Muted bool
Button bool // the link is a small secondary button
Badge *Badge
}
AiaCell is one cell of AiaRows: text, optionally a link, followed by a monospace word (a slug), or a muted note, or a badge.
type AiaChart ¶
type AiaChart struct {
// ID is the card id ("w-ct-first"): the anchor of the attention links.
ID, Title, Description string
Src, Chart string // JSON endpoint and the key under "charts"
// Panels are further keys of the same JSON ("fetches|referrals"), Srcs one
// endpoint per panel when they differ ("a.json|b.json"), PanelLabels the
// title above each panel.
Panels, Srcs, PanelLabels string
// Sum names, per panel ("AI fetches|AI-referred visits"), the one series
// that panel's datasets are added up into.
Sum string
// Ratio ("referrals,pageviews") draws the first chart over the second,
// labelled RatioLabel.
Ratio, RatioLabel string
// Override is JSON restyling a series by name: {"Spoofed":{"cls":"hm-viz--danger"}}.
Override string
Hero bool // taller plot
Cols bool // columns instead of an area
Compare bool // the page is comparing; the legend shows "Previous period"
Table DataTable
}
AiaChart is hm/aia-chart: a titled card whose figure js/aia/page.js fills with an SVG time chart from Src, over the server-rendered Table (which stays readable without JavaScript and behind "Show data").
type AiaOtherPurpose ¶
AiaOtherPurpose is one non-AI purpose row.
type AiaPolicy ¶
AiaPolicy is hm/aia-policy: the Allow / Block choice of one purpose. The owner gets a radio pair named purpose.<id> (so a plain form post carries every purpose); anyone else gets a badge. Legend names the group for screen readers ("Robots policy for all training agents").
type AiaPolicyForm ¶
AiaPolicyForm is hm/aia-policy-start and hm/aia-policy-end, which wrap the agents table in the one form that saves all eight purposes. Return is the page path the save comes back to. A non-owner gets no form and no bar.
type AiaPolicyOnly ¶
type AiaPolicyOnly struct{ Name, Href, Operator string }
AiaPolicyOnly is a robots.txt name without fetches.
type AiaRows ¶
type AiaRows struct {
Caption string
Columns []string
// Right and HiddenHead, when set, are one flag per column: right-aligned
// figures, and a header kept for screen readers but not drawn.
Right, HiddenHead []bool
Rows [][]AiaCell
Page Pagination
Empty string
}
AiaRows is hm/aia-rows: a plain list as a responsive table inside a card the caller already opened (never-fetched pages, failing paths). Cells[i] sits under Columns[i]; the first is the row header. Below 720px each row stacks with the column name above each value. Page.Total above Page.PerPage adds the pager (real links).
type Badge ¶
type Badge struct {
Label string
Kind string // neutral | success | warning | danger | info
// Icon is an optional icon name drawn before the label (the delta arrows).
Icon string
// Plain drops the dot of a neutral label, Wrap lets long text wrap, Mono is a read-only
// identifier or tag (monospace, wraps). A coloured Kind keeps its dot either way.
Plain, Wrap, Mono bool
}
Badge is the hm/badge partial. Status is never conveyed by colour alone: a dot (unless Icon, Plain or Mono is set) and the label always render.
type Bar ¶
Bar is hm/cellbar: a compact proportion bar for a table cell, filled to Pct (0 to 100). Label is its text alternative ("38% of pageviews"); Kind colours it like Progress.
type BarItem ¶
BarItem is one row of a BarList. N sizes the bar; Value is the text shown (formatted by the handler, "1,204"). Note is a muted word after the name (a page type) and Share a muted percentage after the value ("12%").
type BarList ¶
type BarList struct {
Label string // accessible name of the list, required
// NameHeading and ValueHeading are the optional column captions above the
// list ("Source", "Visits").
NameHeading, ValueHeading string
Items []BarItem
Empty string // shown when Items is empty
Quiet bool // paler bars (--chart-bar-quiet), for dense lists
Mono bool // names in the monospace face (paths)
}
BarList is hm/barlist: a ranked list of names, each over a bar as long as its share of the largest value, with the value at the right.
type BulkAction ¶
type BulkAction struct {
Label, Action, Value string
Danger bool
// Confirm makes the button ask first when JavaScript runs ("{n}" is the
// number of checked rows). Without JavaScript the button posts and the
// handler answers with a confirmation page.
Confirm string
}
BulkAction posts the checked row ids to Action.
type Button ¶
type Button struct {
Label string
Variant string // primary | secondary | ghost | danger
Size string // md | sm
Type string // button | submit
Href string // renders an <a>
Icon string
IconOnly bool
AriaLabel string // required with IconOnly
Attrs map[string]string
}
Button is the hm/button partial.
type ButtonMenu ¶
ButtonMenu is a primary button that opens a menu of links (the Create menu).
type Callout ¶
type Callout struct {
Kind, Title, Body, ID, DismissKey string
Compact bool
Attrs map[string]string // extra data-*/aria-* attributes on the root
}
Callout is hm/callout: a titled notice inside the content (not a toast). Kind is info (default), success, warning or danger and picks the icon (error is accepted as danger). Title is optional when there is a Body. A DismissKey adds a dismiss button that is remembered for the browser session.
type CategoryBar ¶
type CategoryBar struct {
Label string // accessible name, required
Segments []CategorySegment
Marker *CategoryMarker
// Columns lays the legend out as rows with the Value and the Share in
// right-aligned columns, as the analytics pages do.
Columns bool
}
CategoryBar is hm/categorybar: one bar split into segments by share, with a legend that names each segment and its value. Marker optionally points at a position on the bar (a target, the current value).
func (CategoryBar) Legend ¶
func (c CategoryBar) Legend() []CategorySeg
Legend is every segment with its colour class, including empty ones.
func (CategoryBar) MarkerAt ¶
func (c CategoryBar) MarkerAt() string
MarkerAt is the marker position clamped to the bar.
func (CategoryBar) Segs ¶
func (c CategoryBar) Segs() []CategorySeg
Segs places the segments end to end. Segments with N <= 0 are skipped on the bar but stay in the legend (Legend).
type CategoryMarker ¶
CategoryMarker points at At percent (0 to 100) of the bar.
type CategorySeg ¶
type CategorySeg struct {
CategorySegment
Class, X, Width string
// First and Last mark the two outer segments: only they get rounded
// corners, so the bar reads as one rounded strip (an SVG rect cannot
// round a single side).
First, Last bool
}
CategorySeg is a segment placed on the bar: X and Width in percent.
type CategorySegment ¶
type CategorySegment struct {
Label, Value, Kind string
// Share is the percentage column of a Columns legend; ignored otherwise.
N float64
}
CategorySegment is one part of a CategoryBar. N sizes it; Value is the text shown in the legend. Kind is success, warning, danger, info or neutral; empty takes the next chart series colour.
type Cell ¶
type Cell struct {
Text string
Link string
Badge *Badge
Depth int // indent of a tree row's name, in levels
Nowrap bool // keep the text on one line (dates)
Clip bool // cut long text with an ellipsis; the full text is the title (addresses)
Sub string // muted monospace line under the text (a URL path)
Initials string // decorative avatar before the text (a person's initials)
Suffix string // muted text after the name, e.g. "(you)"
Tag *Badge // small badge after the text, e.g. "not encrypted"
Bar *Bar // inline proportion bar after the text
Spark *Spark // trend line after the text (a focusable role=img with a summary)
}
Cell is one table cell: text, optionally a link, or a badge, optionally followed by a proportion bar or a trend line. No raw HTML.
type Col ¶
type Col struct {
Key, Label string
Sortable bool
Align string // "" | right
// Role shapes the column: title (takes the slack and wraps), num (right,
// tabular digits), check, actions. With no title column, the first is it.
Role string
// WideOnly drops the column's cells from the compact phone cards (below
// 640px); the header stays in the sort strip only if it is sortable.
WideOnly bool
}
Col is a table column.
type ConfirmHidden ¶
type ConfirmHidden struct{ Name, Value string }
ConfirmHidden is one hidden input of a confirm form.
type Confirmcard ¶
type Confirmcard struct {
Post, Back, Label, Message, CancelLabel, CSRF string
Danger bool
Hidden []ConfirmHidden
}
Confirmcard is hm/confirmcard: the form and card of a confirm page. Post is the action the Confirm button posts to, Back where Cancel goes, Label the Confirm button's text (the action, never "OK"), Message the sentence in the card. Danger makes Confirm red. Hidden are extra fields the form posts.
type DangerConfirm ¶
type DangerConfirm struct {
// ID keeps element ids unique when several cards share a page.
ID string
Title string
// Phrase is what the user must type, compared exactly.
Phrase string
// Prompt is the visible label of the phrase input.
Prompt string
// Action is the form post target; Back is the Cancel link.
Action string
Back string
// Label is the danger submit text; CancelLabel defaults to "Cancel".
Label string
CancelLabel string
CSRF string
// Error is set by the server helper after a failed check.
Error string
Body []DangerText
// Hidden carries extra fields the caller needs re-posted.
Hidden []ConfirmHidden
}
DangerConfirm is the hm/danger-confirm partial: an inline danger card with a typed phrase. The server always checks the posted confirm_phrase (see admin.CheckDangerPhrase); the submit state in the browser is only a hint.
type DangerPart ¶
DangerPart is one text segment, optionally rendered as code or strong.
type DangerText ¶
type DangerText struct{ Parts []DangerPart }
DangerText is one body paragraph made of segments.
type DataTable ¶
type DataTable struct {
Caption string
Columns []string
Rows []DataRow
// Total, when set, is a closing row (column sums).
Total *DataRow
Empty string
// Flat drops the scroll box: the table is as tall as its rows (chart data).
Flat bool
}
DataTable is the hm/datatable partial: the numbers behind a chart as a plain table, readable without JavaScript and by screen readers. The first column is the row header.
type DateCompare ¶
type DateCompare struct {
Field string // query param the switch posts, "compare"
On bool
Disabled bool // no earlier data to compare with
Label2 string // the button's second line, "vs 25 Aug – 23 Sep" (shown only when On)
Help string // "Compared with 25 Aug – 23 Sep."
}
DateCompare is the optional compare switch of hm/daterange. The switch posts Field=1 with the form, so Apply carries it; the caller puts Field=1 on the preset hrefs itself.
type DatePreset ¶
DatePreset is one entry of the picker's preset list: a link (Href) that applies the range at once.
type DateRange ¶
type DateRange struct {
// ID prefixes the popover and input ids (default "range"), so two pickers can share a page.
ID string
Action string
From, To string
Hidden map[string]string
// Label is the picker button text: the matching preset's name and the span ("Last 30 days · 20 Sep – 19 Oct"), else "From - To".
Label string
// Quick is the preset list inside the picker popover; Min and Max bound the
// date inputs (Max is today, UTC).
Quick []DatePreset
Min, Max string
// Compare adds a "Compare to previous period" switch to the popover. Nil (the default) renders the picker unchanged.
Compare *DateCompare
}
DateRange is the hm/daterange partial: a picker button opening from/to date inputs plus presets. Hidden carries the other URL state (tab, agent) through the form.
type Empty ¶
type Empty struct {
Icon, Title, Body string
Actions []Button
// Compact drops the padding and the border for an empty list inside a card.
Compact bool
// Code is a muted status above the title ("404"); Plain centres it with no frame, for a panel.
Code string
Plain bool
// Regular sets the title in normal weight, for a plain sentence rather than a heading.
Regular bool
// H1 makes the title the page heading, for a full-page error.
H1 bool
}
Empty is the hm/empty partial.
type FieldError ¶
type FieldError struct{ ID, Label, Message string }
FieldError links the error summary to a field.
type Filter ¶
type Filter struct {
Name, Label string
Options []Option
// Input renders an <input type=Input> (for example "date") holding Value
// instead of a <select>.
Input, Value string
}
Filter is a select filter above the table.
type Pagination ¶
type Pagination struct {
Page, PerPage, Total int
BaseURL string
Query url.Values
Window int // pages shown each side of the current page (default 2)
// Param is the query parameter that carries the page number (default "page"),
// for a page with more than one list.
Param string
}
Pagination is the hm/pagination partial. Query holds the other URL state (filters, sort) that every page link keeps.
func (Pagination) From ¶
func (p Pagination) From() int
From and To are the 1-based first and last row shown.
func (Pagination) HasPrev ¶
func (p Pagination) HasPrev() bool
HasPrev and HasNext report neighbouring pages.
func (Pagination) Links ¶
func (p Pagination) Links() []PageLink
Links is the windowed page list: first, last, the window around the current page, and gaps.
type Progress ¶
Progress is hm/progress: a labelled bar filled to Pct (0 to 100), with Value as the text at the right ("38%", "12 of 40"). Kind colours the fill: info (default), success, warning or danger.
type RadioCard ¶
type RadioCard struct {
Legend, Name string
// IDPrefix keeps ids unique when a page holds several groups with the same Name.
IDPrefix string
Cols int
Items []RadioCardItem
}
RadioCard is the hm/radiocard partial: radio choices drawn as bordered cards.
type RadioCardItem ¶
type RadioCardItem struct {
Value, Title, Description string
Checked bool
Tag *Badge
Initials string // decorative avatar before the title (a person)
}
RadioCardItem is one card; Tag is an optional badge after the title (for example "Active").
type Row ¶
type Row struct {
ID string
Label string // accessible name of the row (checkbox label)
Cells []Cell
Actions []Action
}
Row is one table row.
func (Row) DangerActions ¶
DangerActions returns the row's destructive actions, in order. A row menu lists them last, behind a separator.
func (Row) SafeActions ¶
SafeActions returns the row's non-destructive actions, in order.
type Savestate ¶
Savestate is the hm/savestate partial: a dot plus text for an editor's save status. State is one of saved, unsaved, saving, error or idle; scripts only change data-state and Text.
type Secret ¶
type Secret struct{ Heading, Note, Value, DismissHref string }
Secret is the hm/secretbanner partial: a one-time value (API key, invite link) shown above a list with Copy and Dismiss. DismissHref is the list URL without the secret, so without JS Dismiss reloads the clean list.
type Segmented ¶
type Segmented struct {
Mode string
Label string
Action string
Name string // required in post and radio modes; unused in buttons mode
CSRF string
Attrs map[string]string // on the container (every mode)
Items []SegmentedItem
}
Segmented is the hm/segmented partial. Mode "" is a form whose buttons post one value each, "radio" a fieldset of radios a surrounding form posts, "buttons" plain buttons a script toggles.
type SegmentedItem ¶
SegmentedItem is one button of a Segmented; Pressed marks the current value. Attrs are script hooks on the button or, in radio mode, the input (every mode).
type Spark ¶
type Spark struct {
Line, Area string
ID string
Summary string
Kind string
// PrevLine and Divider are set only by SparkSplitOf: the earlier period's
// polyline (drawn grey, Line and Area then cover the later period) and the
// x of the divider between the two, in the same box.
PrevLine, Divider string
// Live, when set, leaves Line and Area empty: js/aia/page.js reads the chart of a data
// endpoint and sets the two paths, the label and the tooltip on this same markup.
Live *SparkLive
}
Spark is hm/spark: a small trend line with a gradient area under it, for a KPI card. Line and Area are SVG geometry in a 100 by 24 box that the CSS stretches. Summary is the text alternative ("Trend over 30 days: ending higher"): it is the accessible name and the tooltip of the wrapper, which takes focus so a keyboard user reaches the tooltip (the svg itself is aria-hidden). ID names the gradient; it comes from the raw values and the unit, so the same data always renders the same markup. Kind picks the hue ("series-1" to "series-6", or a status kind); empty is series-4.
func SparkOf ¶
SparkOf draws vals oldest first; nil when there are fewer than two points or nothing but zeros, because a flat line says nothing. unit names a point in the summary ("days", the default, or "weeks").
func SparkSplitOf ¶
SparkSplitOf is SparkOf for a series that compares two periods: vals[:prev] is the earlier one. The earlier period is PrevLine (grey), the later one Line and Area (accent), on one continuous x axis and one y scale, with a divider between them. Without at least one point on each side it is SparkOf.
type SparkLive ¶
SparkLive names the data a live Spark draws: the JSON endpoint Src and the key Chart under "charts". Ratio ("referrals,pageviews") draws the first over the second instead, Dataset picks one dataset of the chart, MinMax stretches min to max instead of starting at zero (shares).
type Stat ¶
type Stat struct {
Label, Value, Detail string
Pct int
// Ring picks the ring card inside a ticker grid; Pct is then the ratio.
Ring bool
Change *StatChange
// Note is the optional muted line under a ticker card.
Note string
// Link is the optional footer link of a ring card ("View more"); a ticker
// card shows it as a plain link under its Note.
Link, LinkLabel string
// Badge replaces Value on a ticker card whose value is a status, not a number
// ("Up to date"): a metric is 30px semibold, a status is a badge.
Badge *Badge
// Spark is the optional trend line under a ticker card's value.
Spark *Spark
}
Stat is one card of hm/stats. Variant "ticker" shows Label, Value and an optional Change, Spark, Note and Link; "ring" shows a progress ring (Pct, 0 to 100) beside the percentage, the Value line ("550 / 1,000") and the Label; "overview" is one card of rings, each item with Label, Detail ("N of M ...") and Pct.
type StatChange ¶
type StatChange struct {
Dir, Text, Tone, Caption string
}
StatChange is the change against the previous period. Dir is "up", "down" or "flat" and picks the arrow and the screen reader word; Tone (success, danger or neutral) picks the badge colour; Text is the amount and Caption what it is measured against.
func StatChangeOf ¶
func StatChangeOf(cur, prev int64, fmtNum func(int64) string) *StatChange
StatChangeOf describes cur against prev, computed from the two numbers; nil when both are zero, because there is nothing to compare. A rise is success-toned; use LowerIsBetter for metrics where it is not.
func (StatChange) Icon ¶
func (c StatChange) Icon() string
Icon is the arrow shown in the delta badge.
func (*StatChange) LowerIsBetter ¶
func (c *StatChange) LowerIsBetter() *StatChange
LowerIsBetter flips the tone for a metric that should fall (spoofed fetches, errors): a rise is danger, a fall is success. It returns c for chaining and is safe on nil.
type TabMore ¶
TabMore is the overflow of a tab row: a "More" button opening a menu of the remaining tabs, with a filter box (Filter is its placeholder) when set. When the current tab is in the menu the button shows its label instead.
type Table ¶
type Table struct {
ID, Caption, BaseURL string
CSRF string
Columns []Col
Rows []Row
SortKey, SortDir string // asc | desc
Query string // search text
SearchLabel string // "" hides the search box
Filters []Filter
// PrimaryFilters (selects) sit beside the search box. PopoverFilters live
// in a "Filters" popover; Chips list the active popover filters, each with
// a link that drops only that one, and ClearHref drops them all. Setting
// either PopoverFilters or Chips selects the filter bar layout over Filters.
PrimaryFilters []Filter
PopoverFilters []Filter
Chips []Chip
ClearHref string
Hidden map[string]string // fixed query values the filter form carries, e.g. the open form
Bulk []BulkAction
BulkURL string
Page Pagination
Empty Empty
Error string // non-empty renders the error state with Retry
// CreatedID marks the row with this ID as just created: it gets the
// hm-row--new class and a visually hidden "(new)" so colour is not alone.
CreatedID string
}
Table is the hm/table partial. State lives in the URL (?q=&sort=&dir=&page=) so tables are linkable and testable.
func (Table) CellClass ¶
CellClass is the class of column i's header and cells: its role and its alignment.
func (Table) ColLabel ¶
ColLabel is the header text of column i ("" when there is none). Cells carry it as data-label so narrow screens can show a label next to each value.
func (Table) FilterBar ¶
FilterBar reports whether the table uses the search + select + popover bar.
func (Table) HasActions ¶
HasActions reports whether any row has actions (adds the actions column).
type Tracker ¶
type Tracker struct {
Label string // accessible name of the row, required
Blocks []TrackerBlock
Start, End string
Legend []TrackerKey
// States draws the analytics cues: hatched danger blocks, shorter warning
// blocks and hollow neutral blocks, so the state is not colour alone.
States bool
}
Tracker is hm/tracker: a row of small blocks, one per period (a day, a check), each coloured by its status. Tip names the block for the tooltip and for screen readers ("Sep 17: 3 errors").
Start and End caption the two ends of the row ("17 Sep", "16 Oct"); Legend names the kinds the blocks use, so colour is never the only cue.
type TrackerBlock ¶
type TrackerBlock struct {
Kind, Tip string
}
TrackerBlock is one block. Kind is success, warning, danger, info or neutral (no data); empty is neutral.
type TrackerKey ¶
type TrackerKey struct {
Kind, Label string
}
TrackerKey is one legend entry of a Tracker: a Kind swatch and its meaning.