1// Copyright (C) 2023 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import m from 'mithril'; 16 17import {Button} from './button'; 18import {HTMLAttrs, HTMLLabelAttrs} from './common'; 19import {Popup} from './popup'; 20import {Intent} from '../widgets/common'; 21 22export interface FormAttrs extends HTMLAttrs { 23 // Text to show on the "submit" button. 24 // Defaults to "Submit". 25 submitLabel?: string; 26 27 // Icon to show on the "submit" button. 28 submitIcon?: string; 29 30 // Text to show on the "cancel" button. 31 // No button is rendered if this value is omitted. 32 cancelLabel?: string; 33 34 // Text to show on the "reset" button. 35 // No button is rendered if this value is omitted. 36 resetLabel?: string; 37 38 // Action to take when the form is submitted either by the enter key or 39 // the submit button. 40 onSubmit?: () => void; 41 42 // Action to take when the form is cancelled. 43 onCancel?: () => void; 44 45 // Prevent default form action on submit. Defaults to true. 46 preventDefault?: boolean; 47} 48 49// A simple wrapper around a <form> element providing some opinionated default 50// buttons and form behavior. Designed to be used with FormLabel elements. 51// Can be used in popups and popup menus and pressing either of the cancel or 52// submit buttons dismisses the popup. 53// See Widgets page for examples. 54export class Form implements m.ClassComponent<FormAttrs> { 55 view({attrs, children}: m.CVnode<FormAttrs>) { 56 const { 57 submitIcon = undefined, 58 submitLabel = 'Submit', 59 cancelLabel, 60 resetLabel, 61 onSubmit = () => {}, 62 preventDefault = true, 63 ...htmlAttrs 64 } = attrs; 65 66 return m( 67 'form.pf-form', 68 htmlAttrs, 69 children, 70 m( 71 '.pf-form-button-bar', 72 m(Button, { 73 type: 'submit', 74 label: submitLabel, 75 rightIcon: submitIcon, 76 className: Popup.DISMISS_POPUP_GROUP_CLASS, 77 intent: Intent.Primary, 78 onclick: (e: Event) => { 79 preventDefault && e.preventDefault(); 80 onSubmit(); 81 }, 82 }), 83 // This cancel button just closes the popup if we are inside one. 84 cancelLabel && 85 m(Button, { 86 type: 'button', 87 label: cancelLabel, 88 className: Popup.DISMISS_POPUP_GROUP_CLASS, 89 }), 90 // This reset button just clears the form. 91 resetLabel && 92 m(Button, { 93 label: resetLabel, 94 type: 'reset', 95 }), 96 ), 97 ); 98 } 99} 100 101// A simple wrapper around a <label> element. Designed to be used within Form 102// widgets in combination with input controls to provide consistent label 103// styling. 104// 105// Like normal labels, FormLabels provide a name for an input while also 106// improving their hit area which improves a11y. 107// 108// Labels are bound to inputs by placing the input inside the FormLabel widget, 109// or by referencing the input's "id" tag with a "for" tag. 110export class FormLabel implements m.ClassComponent<HTMLLabelAttrs> { 111 view({attrs, children}: m.CVnode<HTMLLabelAttrs>) { 112 return m('label.pf-form-label', attrs, children); 113 } 114} 115