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