• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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