xref: /aosp_15_r20/external/perfetto/ui/src/widgets/form.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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