UNPKG

@thebase/ui

Version:

CDN-installable Owl and Bootstrap 5 UI component library.

203 lines (180 loc) • 6.45 kB
# Form Build an accessible Bug Report form with BaseUI `Field` layout, BaseUI `Button` actions, and Owl `t-model` input bindings. ## Pure Owl component ```js import { Component, useState, xml } from "@base/owl"; import { Button, Field, FieldDescription, FieldGroup, FieldLabel, } from "@thebase/ui"; class BugReportExample extends Component { static components = { Button, Field, FieldDescription, FieldGroup, FieldLabel, }; static template = xml` <form class="bu-form" data-slot="form" novalidate="novalidate" t-on-submit="submit"> <div class="bu-form-header"> <h3 class="bu-form-title">Bug Report</h3> <p class="bu-form-description">Help us improve by reporting bugs you encounter.</p> </div> <FieldGroup className="'bu-form-fields'"> <Field> <FieldLabel for="'bug-title'">Bug Title</FieldLabel> <input id="bug-title" name="title" class="form-control bu-form-control" type="text" placeholder="Login button not working on mobile" autocomplete="off" t-model="state.title" /> </Field> <Field> <FieldLabel for="'bug-description'">Description</FieldLabel> <div class="bu-form-input-group" data-slot="input-group" role="group"> <textarea id="bug-description" name="description" class="form-control bu-form-textarea" placeholder="I'm having an issue with the login button on mobile." maxlength="100" rows="6" t-model="state.description" ></textarea> <div class="bu-form-counter" data-slot="input-group-addon" data-align="block-end"> <span class="bu-form-counter-text"> <t t-esc="state.description.length"/>/100 characters </span> </div> </div> <FieldDescription>Include steps to reproduce, expected behavior, and what actually happened.</FieldDescription> </Field> </FieldGroup> <Field orientation="'horizontal'" className="'bu-form-actions'"> <Button type="'button'" variant="'outline'" onClick="() => this.reset()">Reset</Button> <Button type="'submit'">Submit</Button> </Field> </form> `; setup() { this.state = useState({ title: "", description: "", }); } reset() { this.state.title = ""; this.state.description = ""; } submit(event) { event.preventDefault(); console.log({ title: this.state.title, description: this.state.description, }); } } ``` ```base-ui <form class="bu-form" data-slot="form" novalidate="novalidate" t-on-submit="submit"> <div class="bu-form-header"> <h3 class="bu-form-title">Bug Report</h3> <p class="bu-form-description">Help us improve by reporting bugs you encounter.</p> </div> <FieldGroup className="'bu-form-fields'"> <Field> <FieldLabel for="'bug-title'">Bug Title</FieldLabel> <input id="bug-title" name="title" class="form-control bu-form-control" type="text" placeholder="Login button not working on mobile" autocomplete="off" t-model="state.title" /> </Field> <Field> <FieldLabel for="'bug-description'">Description</FieldLabel> <div class="bu-form-input-group" data-slot="input-group" role="group"> <textarea id="bug-description" name="description" class="form-control bu-form-textarea" placeholder="I'm having an issue with the login button on mobile." maxlength="100" rows="6" t-model="state.description" ></textarea> <div class="bu-form-counter" data-slot="input-group-addon" data-align="block-end"> <span class="bu-form-counter-text"> <t t-esc="state.description.length"/>/100 characters </span> </div> </div> <FieldDescription>Include steps to reproduce, expected behavior, and what actually happened.</FieldDescription> </Field> </FieldGroup> <Field orientation="'horizontal'" className="'bu-form-actions'"> <Button type="'button'" variant="'outline'" onClick="() => this.reset()">Reset</Button> <Button type="'submit'">Submit</Button> </Field> </form> ``` This is the same Bug Report form converted from static `b-ui` markup to pure Owl composition: `FieldGroup`, `Field`, `FieldLabel`, `FieldDescription`, and `Button` replace the static adapters, while `t-model` owns the input state. ## State | Field | Binding | Notes | | --- | --- | --- | | `title` | `t-model="state.title"` | trims or validates in your submit handler if needed | | `description` | `t-model="state.description"` | drives the live `state.description.length` counter | ## Static component ```base-ui <form b-ui="form"> <div class="bu-form-header"> <h3 class="bu-form-title">Bug Report</h3> <p class="bu-form-description">Help us improve by reporting bugs you encounter.</p> </div> <div b-field-group class="bu-form-fields"> <div b-ui="field"> <label b-field-label for="bug-title">Bug Title</label> <input b-ui="input" id="bug-title" name="title" type="text" placeholder="Login button not working on mobile" autocomplete="off" > </div> <div b-ui="field"> <label b-field-label for="bug-description">Description</label> <div class="bu-form-input-group" data-slot="input-group" role="group"> <textarea b-ui="textarea" id="bug-description" name="description" placeholder="I'm having an issue with the login button on mobile." maxlength="100" rows="6" ></textarea> <div class="bu-form-counter" data-slot="input-group-addon" data-align="block-end"> <span b-form-counter>0/100 characters</span> </div> </div> <p b-field-description>Include steps to reproduce, expected behavior, and what actually happened.</p> </div> </div> <div b-ui="field" b-att-orientation="horizontal" class="bu-form-actions"> <button b-ui="button" b-att-variant="outline" b-form-reset type="button">Reset</button> <button b-ui="button" type="submit">Submit</button> </div> </form> ```