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'; 16import {Button} from './button'; 17import {HTMLAttrs, HTMLLabelAttrs} from './common'; 18import {Popup} from './popup'; 19import {Intent} from '../widgets/common'; 20 21export interface FormAttrs extends HTMLAttrs { 22 // Text to show on the "submit" button. 23 // Defaults to "Submit". 24 submitLabel?: string; 25 26 // Icon to show on the "submit" button. 27 submitIcon?: string; 28 29 // Text to show on the "cancel" button. 30 // No button is rendered if this value is omitted. 31 cancelLabel?: string; 32 33 // Text to show on the "reset" button. 34 // No button is rendered if this value is omitted. 35 resetLabel?: string; 36 37 // Action to take when the form is submitted either by the enter key or 38 // the submit button. 39 onSubmit?: () => void; 40 41 // Action to take when the form is cancelled. 42 onCancel?: () => void; 43 44 // Prevent default form action on submit. Defaults to true. 45 preventDefault?: boolean; 46} 47 48// A simple wrapper around a <form> element providing some opinionated default 49// buttons and form behavior. Designed to be used with FormLabel elements. 50// Can be used in popups and popup menus and pressing either of the cancel or 51// submit buttons dismisses the popup. 52// See Widgets page for examples. 53export class Form implements m.ClassComponent<FormAttrs> { 54 view({attrs, children}: m.CVnode<FormAttrs>) { 55 const { 56 submitIcon = undefined, 57 submitLabel = 'Submit', 58 cancelLabel, 59 resetLabel, 60 onSubmit = () => {}, 61 preventDefault = true, 62 ...htmlAttrs 63 } = attrs; 64 65 return m( 66 'form.pf-form', 67 htmlAttrs, 68 children, 69 m( 70 '.pf-form-button-bar', 71 m(Button, { 72 type: 'submit', 73 label: submitLabel, 74 rightIcon: submitIcon, 75 className: Popup.DISMISS_POPUP_GROUP_CLASS, 76 intent: Intent.Primary, 77 onclick: (e: Event) => { 78 preventDefault && e.preventDefault(); 79 onSubmit(); 80 }, 81 }), 82 // This cancel button just closes the popup if we are inside one. 83 cancelLabel && 84 m(Button, { 85 type: 'button', 86 label: cancelLabel, 87 className: Popup.DISMISS_POPUP_GROUP_CLASS, 88 }), 89 // This reset button just clears the form. 90 resetLabel && 91 m(Button, { 92 label: resetLabel, 93 type: 'reset', 94 }), 95 ), 96 ); 97 } 98} 99 100// A simple wrapper around a <label> element. Designed to be used within Form 101// widgets in combination with input controls to provide consistent label 102// styling. 103// 104// Like normal labels, FormLabels provide a name for an input while also 105// improving their hit area which improves a11y. 106// 107// Labels are bound to inputs by placing the input inside the FormLabel widget, 108// or by referencing the input's "id" tag with a "for" tag. 109export class FormLabel implements m.ClassComponent<HTMLLabelAttrs> { 110 view({attrs, children}: m.CVnode<HTMLLabelAttrs>) { 111 return m('label.pf-form-label', attrs, children); 112 } 113} 114