package gallery import ( "errors" "fmt" "html/template" "strings" "amadan.net/rastrillo/fiesta/example" "amadan.net/rastrillo/fiesta/internal/codeview" ) // The preview widget: Desktop, Mobile and HTML over one frame, as // Rastrillo's gallery draws it, without its Template tab. The frame // shows the state's own document at a virtual width and a measured // height; the HTML tab shows the markup a reader copies, without the // container the manifest's wrapper puts it in, and names that // container on the line above. A grouped example (status-pill, badge, // meter) is one widget whose frame is a row document of every state, // with one code block per state. // previewView is one widget. Group names the widget's radio group, // unique on the page. Style carries the frame's virtual heights // (--ds-h and --ds-hm). Class is " ds-view--page" on the examples whose // document is a whole page and empty on the rest, with its own leading // space so the template writes class="ds-view{{.Class}}" without a // conditional; a grouped widget adds " ds-view--rows". Wrapper is the // line naming the container a wrapped sample needs; Source the markup // the HTML tab shows, formatted and highlighted. NoCopy marks a block // that offers no Copy button, as Rastrillo does for an Illustration; no // Fiesta example is one. Rows is a grouped example's code, one block // per state, and Source is empty then. type previewView struct { Group string Style template.CSS Class string Src string Wrapper template.HTML Source template.HTML Title string NoCopy bool Rows []rowCode } // rowCode is one state of a grouped example in the HTML panel. type rowCode struct { State string Source template.HTML } // HasHTML says whether the widget draws an HTML tab: it has markup to // show, as one block or as a grouped example's rows. func (v previewView) HasHTML() bool { return v.Source != "" || len(v.Rows) > 0 } // grouped names the examples shown as one widget: a row of every state // in one frame, and one code block per state. Rastrillo's three. var grouped = map[string]bool{"status-pill": true, "badge": true, "meter": true} // pageFrame reports whether an example's document is a whole page // rather than a component inside one: the layout documents, the two // shell idioms and the modal, whose backdrop is fixed to the frame's // viewport and wants a window-sized one. It picks the widget's width // class: a page lays out at a virtual 1200px, everything else at // 900px; view.css carries the argument for the two numbers. The // sign-in screens are components, as in Rastrillo: a card, not a // window. Getting this wrong costs a rendering, never a broken page. func pageFrame(e example.Entry) bool { return e.Document || strings.HasPrefix(e.Name, "shell-") || e.Name == "modal" } // previewClass is pageFrame as the template writes it. func previewClass(e example.Entry) string { if pageFrame(e) { return " ds-view--page" } return "" } // wrapperMarkup is the opening markup of the container a manifest // wrapper puts a body in, as the HTML tab names it. The seeded form's // method and action are left out: they belong to the reader's form, // and the seed's action="#" is a placeholder nobody should copy. "" is // no wrapper; anything else the manifest does not know is an error. func wrapperMarkup(w string) (string, error) { switch w { case "list": return `