Forms

FormRow

Fields side by side, equal or weighted, that stack one under another on a phone.

#forms#layout#grid#no-js

Demo

Preview

Get it

It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.

$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/form_row.qwe
main.qwe
import ui/theme.qwe use theme_cssuse ui/form_row.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>

Example

The code of the preview above.

demos/form_row.qwe
view FormRowDemo() =    <div.demo-stack>        <FormRow class="form-row-demo-names">            <TextField name="first" label="First name" field="form-row-demo-first"/>            <TextField name="last" label="Last name" field="form-row-demo-last"/>        </FormRow>        <FormRow columns={[3, 1]} class="form-row-demo-city">            <TextField name="city" label="City" field="form-row-demo-city"/>            <TextField name="zip" label="Postcode" field="form-row-demo-zip"/>        </FormRow>        <FormRow columns={["1fr", "auto"]} align="end" class="form-row-demo-search">            <TextField name="q" label="Search" placeholder="A name or an email" field="form-row-demo-q"/>            <Button type="button">Search</Button>        </FormRow>        <FormRow gap={20} class="form-row-demo-three">            <TextField name="day" label="Day" field="form-row-demo-day"/>            <TextField name="month" label="Month" field="form-row-demo-month"/>            <TextField name="year" label="Year" field="form-row-demo-year"/>        </FormRow>    </div>

Source

ui/form_row.qwe
// FormRow: fields side by side (first name and last name, city and postcode),// each as wide as the others unless told, stacking one under another on a phone.////   <FormRow>//       <TextField name="first" label="First name"/>//       <TextField name="last" label="Last name"/>//   </FormRow>//   <FormRow columns={[3, 1]}> <TextField name="city" label="City"/> <TextField name="zip" label="Postcode"/> </FormRow>//   <FormRow align="end"> <TextField name="q" label="Search"/> <Button type="submit">Go</Button> </FormRow>//// columns: each child's share of the width, as numbers ([2, 1]: the first twice// as wide), or CSS widths ("1fr", "12ch", "auto"); none: equal shares. gap: pixels// between them (12). align: how they line up across, "start" (default), "center"// or "end" (buttons level with the inputs beside them). stack: they go one under// another on a phone (under 560px; true); false keeps them side by side.import ui/theme.qwe use ui_clslet form_row_css = css`.ui-form-row { display: flex; gap: var(--ui-form-row-gap, 12px); align-items: flex-start; min-width: 0; }.ui-form-row > * { flex: 1 1 0; min-width: 0; }.ui-form-row-cols { display: grid; grid-template-columns: var(--ui-form-row-cols); }.ui-form-row-center { align-items: center; }.ui-form-row-end { align-items: flex-end; }@media (max-width: 559px) {  .ui-form-row:not(.ui-form-row-keep) { flex-direction: column; align-items: stretch; grid-template-columns: minmax(0, 1fr); }  .ui-form-row:not(.ui-form-row-keep) > * { flex-basis: auto; }}`// "2fr 1fr" from [2, 1], or the widths as given.fn form_row_cols(columns: list) -> str =    columns | map((c) => type_of(c) == "int" || type_of(c) == "float" ? `${c}fr` : str(c)) | join(" ")view FormRow(columns: list? = null, gap: int = 12, align: str = "start", stack: bool = true, class: str? = null, children) {    style global form_row_css    <div class={ui_cls(["ui-form-row", columns != null && "ui-form-row-cols", align != "start" && `ui-form-row-${align}`,                        !stack && "ui-form-row-keep", class])}         style={`${columns != null ? `--ui-form-row-cols: ${form_row_cols(columns)}; ` : ""}--ui-form-row-gap: ${gap}px`}>        {children}    </div>}
Thread
58Useful? Like it, or add to its thread below.

Thread 0 posts

On FormRow: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.